Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I print the schema in HotChocolate as GraphQL SDL

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
}
like image 452
Michael Ingmar Staib Avatar asked Jan 14 '21 10:01

Michael Ingmar Staib


People also ask

How do I extract a schema from GraphQL?

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.

What is GraphQL schema file?

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.

How do I create a schema in hot chocolate?

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.

What is GraphQL schema?

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:

What is SDL (schema definition language)?

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.

How to create a simple hello world schema in GraphQL?

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.


Video Answer


3 Answers

Hot Chocolate Server provides easy ways to print the schema as GraphQL SDL.

  1. 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.

  2. 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.

like image 102
Michael Ingmar Staib Avatar answered Nov 26 '22 11:11

Michael Ingmar Staib


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 ?? "";
}
like image 23
StillLearnin Avatar answered Nov 26 '22 11:11

StillLearnin


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;
}
like image 41
Thomas Avatar answered Nov 26 '22 11:11

Thomas