How to build GraphQL APIs with ASP.NET Core & HotChocolate - Part 1 - Setup
Tags: aspnetcore
Published: 2020-08-08 17:55:52

Getting started with GraphQL as a .NET developer is **much simpler than you would think**. Let me show you why.

Coming from a REST or MVC background GraphQL looks scary. 

I know.

It is very different from what we are used to, especially in the .NET (Core) ecosystem. 

There's no (built-in) template. With traditional RESTful APIs (or MVC apps for that matter) you select your template and you get a ready-to-run solution right away. Not with GraphQL. This makes it look like GraphQL on ASP.NET Core is complicated and a pain to get started with.

I am here to show you, **it is not**.

**In this article I will show you how to:**
- Set up HotChocolate and GraphiQL for your ASP.NET Core application.
- Define types from your GraphQL schema using C#.
- Create your resolvers to wire up real data to those types. (Part 2)
- Implement pagination. (Part 2)

**Who is this article for?**

This series of articles focuses on **authoring GraphQL APIs using the ASP.NET Core platform.**

I am going to assume **you have already acquired a solid understanding of the fundamental principles of GraphQL itself**. If not, I would suggest heading over to [https://graphql.org/](https://graphql.org/) and going through the documentation first.

We will not go into advanced topics - such as directives, fragments, custom scalars, etc, not even mutations - but **you are expected to understand the basics of the type system, queries, lists, nullability, and enums**.

## The API you are going to build by the end of this article 

I don't like overly simplified tutorials, they usually miss out on the most important architectural problems.

Instead, here we are going to pretend we're in charge of building a real-world API of an airline travel company: The dataset consists of airlines, airports, and routes between them. The dataset that we are going to use is a full-scale real-world snapshot of said data.

I built a NuGet package that contains all our data, so we don't have to worry about a database now, **we can instead focus on the important part: GraphQL**.

I strongly believe APIs should be built [design-first](https://apisyouwonthate.com/blog/api-design-first-vs-code-first) so that's what we are going to do. 

Let's pretend this is the schema our architects built and was given to us for implementation:
```graphql
type Query{
	routes(offset: Int, limit: Int): [Route!]!
	airlines(offset: Int, limit: Int): [Airline!]!
}

type Route{
	airline: Airline!
	source: Airport!
	destination: Airport!
	codeshare: Boolean!
	stops: Int!
}

type Airline{
	id: ID!
	name: String!
	iata: String
	origin: Country!
	destinations: [Airport!]!
	routes: [Route!]!
}

type Airport{
	id: ID!
	name: String!
	city: String!
	country: Country!
	iata: String
	timezone: Float!
	airlines: [Airline!]!
	routes: [Route!]!
}

type Country{
	name: String!
	isoCode: String!
	dafifCode: String!
}

schema{
	query: Query
}
```

We have the schema, we have the "database", so let's get started. 

## Project setup (very simple)

I promised you this is going to be very simple. So here it is:

We are going to start with an **Empty** *ASP.NET Core 3.1* project template. We can even get rid of the `UseEndpoints` call, so our method looks like this:
```csharp
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

        app.UseRouting();
    }
}
```

Can't get much simpler, right?

## Adding HotChocolate from NuGet

As you might have noticed, ASP.NET Core does not include GraphQL support by default. This isn't going to stop us though, there are **two great GraphQL server implementations** for ASP.NET Core: *graphql-dotnet* and *HotChocolate*. I am not going to talk about the differences here, but my choice is *HotChocolate* which we're going to use for this tutorial. Having said that, all I am going to show you here could just as well be achieved with *graphql-dotnet*.

Let's install 3 HotChocolate NuGet packages:
- *HotChocolate* - contains the core GraphQL server logic
- *HotChocolate.AspNetCore* - contains the AspNetCore bindings
- *HotChocolate.AspNetCore.GraphiQL* - this one is optional, contains [graphiql](https://github.com/graphql/graphiql) an amazing GraphQL playground we can use to test-drive our server.

### Configuring the GraphQL middleware

Let's add these two lines at the end of `Configure`:
```csharp
      app.UseGraphiQL();
      app.UseGraphQL();
```

This wires up both HotChocolate and GraphiQL to our application.

## Configuring your GraphQL schema

If you tried to run the above, it crashes on startup with some cryptic error message. That is because we haven't told HotChocolate what schema we'd like to use for our endpoint. So let's do that.

### Step 1: the schema file

A wonderful feature of HotChocolate is that it can read our schema from the `.graphql` file directly, without us having to transform it into C# syntax.

To do that, we have to add the schema file to our project (I am going to call it "schema.graphql") and make sure to set the `CopyToOutputDirectory` property on it, so it gets placed right next to our output dll.

### Step 2: `ConfigureServices`

Now that we have our file in the project let's tell HotChocolate to load it. This is done inside `ConfigureServices`, like so:

```csharp
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGraphQL(
            SchemaBuilder.New()
                .AddDocumentFromFile("./schema.graphql")
                .Create()
        );
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

        app.UseRouting();

        app.UseGraphiQL();
        app.UseGraphQL();
    }
}
```

If you run your app again, you should now be facing a new error message:

![Schema errors](https://dev-to-uploads.s3.amazonaws.com/i/s2i3n486zarydyeuzdsv.png)

**This is great.** It means the schema is recognized and HotChocolate doesn't know how to serve it yet - because we haven't written the logic for it yet. It is like a series of `NotImplementedException`s.

**The setup part is complete here.**

Our goal for the next part of this article will be to add all backing *Type* and *Resolver* classes for all these GraphQL types until all the error messages are gone.

## Conclusion

In just a few minutes, **you set up a GraphQL server** configuration in your ASP.NET Core application.

Thank you for reading this first part of the article, feel free to share if you liked it.

In the second part of the series, **we will cover implementing the actual GraphQL types** for this airline example: Query, Route, Airport, et cetera.

In the meanwhile, you can check out [the Github Repository](https://github.com/marcelltoth/graphqlairlines-demo/tree/master/GraphQlAirlines.Api) containing the final source code of our sample API.