It would be great for development with Relay to print the GraphQL SDL directly with the Hot Chocolate GraphQL server. Is there a way to do this?
schema {
query: Query
}
type Query {
sayHello: String
}
How To Get The Schema — Introspection Queries. Some GraphQL servers don't provide a convenient GraphQL API explorer. Instead, to get the schema we need to send a HTTP request to the GraphQL server endpoint asking for the GraphQL schema. This type of HTTP request is called a GraphQL introspection query.
Your GraphQL server uses a schema to describe the shape of your available data. This schema defines a hierarchy of types with fields that are populated from your back-end data stores. The schema also specifies exactly which queries and mutations are available for clients to execute.
Incoming queries are validated and executed against that schema. In Hot Chocolate a schema is created by using the SchemaBuilder. With the schema builder we can define what types our schema will have and how data is resolved. There are basically two ways to define a schema, with code or with the GraphQL SDL.
It’s a language with a very simple syntax that allows to define a schema very succinctly. Once you have a gasp at the different syntax elements of the SDL, you’ll be able to write schemas in no time flat. Here’s what a basic GraphQL schema deffinition for a simple todo app could look like:
GraphQL schemas for a service are now most often specified using what’s known as the GraphQL SDL (schema definition language), also sometimes referred to as just GraphQL schema language. It’s a language with a very simple syntax that allows to define a schema very succinctly.
In schema-first we could create a simple hello world schema like the following: In code-first we can again choose two approaches and again we can mix and match them. The first approach is to define the GraphQL types via POCOs and infer the GraphQL schema type structure with conventions.
Hot Chocolate Server provides easy ways to print the schema as GraphQL SDL.
You can print any schema by calling ToString
on ISchema
.
This is a more programmatic way to do it, but never the less it can be quite useful to just print the schema in tests or console tools. Good to know here is that any syntax node will allow you to be printed that way. So, even if you want to print a parsed query, you can just do ToString
on it to get its GraphQL language string representation.
For things like Relay, it is quite useful to have the schema available on an endpoint to just download it. Hot Chocolate server provides in all versions a GraphQL SDL endpoint.
Version 10 and earlier: http://localhost:5000/graphql/schema
Version 11 and newer: http://localhost:5000/graphql?sdl
This URL should be valid when hosting the GraphQL endpoint on the graphql
route.
If you are using code first with attributes to automatically generate your schema, here is an example of how to get an instance of the schema and write it to a file if it has changed.
I placed this code in Program.cs
so it auto-generates my schema.graphql
file for my front end tooling when my aspnet.core project starts during development.
HostInstance = builder.Build();
if(Debugger.IsAttached)
{
var resolver = HostInstance.Services.GetService<IRequestExecutorResolver>();
if (resolver != null)
{
var executor = resolver.GetRequestExecutorAsync().Result;
if (executor != null)
{
var schemaFile = Path.Combine(ProjectPathInfo.ProjectPath, "Apps\\src\\lib\\com\\GraphQL\\schema.graphql");
var newSchema = executor.Schema.ToString();
var oldSchema = File.ReadAllText(schemaFile);
if (newSchema != oldSchema)
File.WriteAllText(schemaFile, newSchema);
}
}
}
I use this supporting internal class (borrowed from here) to find the project folder to use for the output of the SDL.
internal static class ProjectPathInfo
{
public static string CSharpClassFileName = nameof(ProjectPathInfo) + ".cs";
public static string CSharpClassPath;
public static string ProjectPath;
public static string SolutionPath;
static ProjectPathInfo()
{
CSharpClassPath = GetSourceFilePathName();
ProjectPath = Directory.GetParent(CSharpClassPath)!.FullName;
SolutionPath = Directory.GetParent(ProjectPath)!.FullName;
}
private static string GetSourceFilePathName([CallerFilePath] string callerFilePath = null) => callerFilePath ?? "";
}
If you want to generate the schema in CI/CD, you can add a CLI argument that generates the schema and doesn't start the app. Something like:
In Program.cs:
if (args.Any(c => c == "--generate-schema"))
{
builder.Services.AddGraphQL().InitializeOnStartup();
var app = builder.Build();
var executor = host.Services.GetRequiredService<IRequestExecutorResolver>().GetRequestExecutorAsync().Result;
var schema = executor.Schema.Print();
File.WriteAllText("schema.graphql", schema);
return;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With