How YOU can build a Web API using GraphQL .Net Core and Entity Framework
Tags: webdev, tutorial, dotnet, graphql
Published: 2019-08-29 20:56:06

---
title: How YOU can build a Web API using GraphQL .Net Core and Entity Framework
published: true
description: This shows how to build a Web Api with GraphQL and Entity Framework for storage
tags: webdev, tutorial, dotnet, graphql
---

# Building a Web Api using GraphQL .Net Core and Entity Framework

In this article we will learn:

- **Build a Web Api**, we will learn how to scaffold a Web Api using the .Net Core CLI and how different classes respond to different requests
- **Integrate GraphQL**, we will create the necessary helper classes to create things such as Schema, Resolvers. Additionally, we will learn to work with the visual environment GraphiQL
- **Set up Entity Framework** and mapping classes to tables, here we will set up a class with entities that will create corresponding tables and columns in a database. We will also integrate EF with our API 

Here's the repo for this article:

> https://github.com/softchris/graphql-ef-demo

## Resources

- [Article on creating webapi in .Net Core](https://docs.microsoft.com/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&tabs=visual-studio&wt.mc_id=devto-blog-chnoring)

- [Building your first Graphql app in .Net Core](https://dev.to/dotnet/learn-how-you-can-use-graphql-in-net-core-and-c-4h96)
Teaches you how to create your first app in .Net Core using GraphQL. This talks about fundamental topics such as Query, Mutation, Resolvers and more.

- [Building a Serverless Api with GraphQL in .Net Core](https://dev.to/azure/how-you-can-build-a-serverless-api-using-graphql-net-core-c-and-vs-code-g5h)
This covers how to build a Serverless API with an underlying GraphQL API.

- [Article I based this article on](https://developer.okta.com/blog/2019/04/16/graphql-api-with-aspnetcore)
This is an excellent article in many ways. It does use a different and more verbose approach to setting up GraphQL. It's up to you which approach you want to use

- [Deploy your .Net Core app to the Cloud](https://docs.microsoft.com/aspnet/core/tutorials/publish-to-azure-webapp-using-vscode?view=aspnetcore-2.2?wt.mc_id=devto-blog-chnoring)
This teaches you how to deploy from VS Code

- [Free Azure account](https://azure.microsoft.com/free/?wt.mc_id=devto-blog-chnoring)
To deploy Serverless Azure Functions you will need a free Azure account)


## Build our Web Api

The first thing we will do is to scaffold a .Net Core project. We will use a template called `webapi`. The command is as follows:

```
dotnet new webapp -o aspnetcoreapp
```

This will create a Web Api project in a folder `aspnetcoreapp`. The flag `-o` says what to name the directory. So you can replace `aspnetcoreapp` with a name of your choosing. 

If you've never built a Web Api in .Net Core before I recommend having a look at the Web Api link as mentioned in `Resources`. I will say this though. The idea is to have a concept of routes that you match to controllers. In a normal looking Wep Api you would normally have a route `api/Products` that would be handled by a `ProductsController` class. We will look at this a bit closer when we implement the GraphQL part. 

## Integrate GraphQL

We will take the following steps to integrate GraphQL:

1. **Install** dependencies from NuGet
2. **Define** a Schema with custom types, query types and mutations
3. **Create** resolver functions that will respond to requests
4. **Add a Web Api route** to respond to requests from GraphiQL, our visual environment

### Install dependencies

First ensure we are inside of our project directory:

```
cd aspnetcoreapp
```

Now install the dependencies like so:

```
dotnet add package GraphQL --version 2.4.0
dotnet add package graphiql --version 1.2.0
```

The package `GraphQL` will give us the needed core library to set up a schema, and define resolvers. `graphiql` package is a visual environment that we will use to show how great the developer experience is with it.

### Set up schema

Create a `Graphql` directory like so:

```
mkdir Graphql
```

Now create a file `Schema.cs` and give it the following content:

```csharp
using GraphQL.Types;
using GraphQL;
using Api.Database;

namespace Api.Graphql 
{
  public class MySchema 
  {
    private ISchema _schema { get; set; }
    public ISchema GraphQLSchema 
    {  
      get 
      {
        return this._schema;
      }
    }
    
    public MySchema() 
    {
      this._schema = Schema.For(@"
          type Book {
            id: ID
            name: String,
            genre: String,
            published: Date,
            Author: Author
          }

          type Author {
            id: ID,
            name: String,
            books: [Book]
          }

          type Mutation {
            addAuthor(name: String): Author
          }

          type Query {
              books: [Book]
              author(id: ID): Author,
              authors: [Author]
              hello: String
          }
      ", _ =>
      {
        _.Types.Include<Query>();
        _.Types.Include<Mutation>();
      });
    }

  }
}
```

Let's break down what we just did. `Query` and `Mutation` are reserved words. `Query` is our public API, anything we put in here can be queried for. `Mutation` is also part of the public API but signals that we want to change data. Our only entry is `addAuthor` that will allow us to create an Author. `Author` and `Book` are custom types that we just defined and have some suitable properties on them. 

### Querying

If you haven't read any of my other articles on GraphQL I recommend having a look at the resource section but here's a quick run-through of how it works to query things in GraphQL. Given our schema above we can query for `books`. It could look like this:

```
{ 
  books { 
    name,
    genre,
    published
  }
}
```

This would give a response like so:

```json
{
  "data": {
    "books" : [{
      "name": "IT",
      "genre": "Horror",
      "published": "1994"
    }]
  } 
}
```

One of the great things about GraphQL is that it allows for us to go at depth and ask for even more data, so we could be asking for it to list the author as well in our query above, like so:

```
{
  books {
    name, 
    genre,
    published,
    author {
      name
    }
  }
}
```

with the corresponding answer:

```json
{
  "data": {
    "books" : [{
      "name": "IT",
      "genre": "Horror",
      "published": "1994",
      "author": {
        "name": "Stephen King"
      }
    }]
  } 
}
```

### Define resolvers

Before we go so far as defining resolvers we need a couple of types. We need to create `Author` and `Book`. 

**Create types**

First create a file `Author.cs` under a directory `Database`. Give it the following content:

```csharp
// Database/Author.cs

using System.Collections.Generic;

namespace Api.Database
{
  public class Author
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Book> Books { get; set; }
  }
}
```

Now create the `Book.cs` also that one under the `Database` directory:

```csharp
// Database/Book.cs

namespace Api.Database 
{
  public class Book
  {
    public string Id { get; set; }

    public string Name { get; set; }

    public bool Published { get; set; }

    public string Genre { get; set; }

    public int AuthorId { get; set; }

    public Author Author { get; set; }
  }
}
```

**Create Query resolver**

Now let's define the corresponding resolvers. In our Schema.cs we mentioned `Query` and `Mutation`, classes we are yet to define. Let's start by creating `Query.cs` and give it the following content:

```csharp
// Graphql/Query.cs

using System.Collections.Generic;
using GraphQL;
using System.Linq;
using Api.Database;
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;

namespace Api.Graphql 
{
  public class Query
  {

    [GraphQLMetadata("books")]
    public IEnumerable<Book> GetBooks()
    {
      return Enumerable.Empty<Books>();
    }

    [GraphQLMetadata("authors")]
    public IEnumerable<Author> GetAuthors() 
    {
      return Enumerable.Empty<Authors>();
    }

    [GraphQLMetadata("author")]
    public Author GetAuthor(int id)
    {
      return null;
    }

    [GraphQLMetadata("hello")]
    public string GetHello()
    {
      return "World";
    }
  }
}
```

We have created a class above that handles every request to query in our schema. We've also created a method that corresponds to everything we can query for. The decorator `GraphQLMetadata` helps us to map what's written in the Schema to a method, a *resolver*. For example, we can see how `author(id: ID): Author` is mapped to the following code in the `Query` class:

```csharp
[GraphQLMetadata("author")]
public Author GetAuthor(int id)
{
  return null;
}
```

**Create Mutation resolver**

We have one more resolver to define namely `Mutation`. Let's create `Mutation.cs` with the following content:

```csharp
using Api.Database;
using GraphQL;

namespace Api.Graphql 
{
  [GraphQLMetadata("Mutation")]
  public class Mutation 
  {
    [GraphQLMetadata("addAuthor")]
    public Author Add(string name)
    {
      return null;
    }
  }
}
```

### Adding the GraphQL route

When it comes to GraphQL the whole point is to only have one route `/graphql` and for a *negotiation* to happen between frontend and backend about what content should be returned back. We will do two things:

1. Map GraphiQL to `/graphql`
2. Create a controller to respond to `/graphql`

**Map GraphiQL**

GraphiQL is visual environment and something we installed from NuGet. To be able to use it we need to open up `Startup.cs` and in the method `Configure()` we need to add the following line:

```
app.UseGraphiQl("/graphql");
```

NOTE, make sure to add the above line before `app.UseMvc();`

**Create a GraphQL Controller**

Under the directory `Controllers` let's create a file `GraphqlController.cs`. Let's build up this file gradually. Let's start with the class definition:

```csharp
// GraphqlController.cs

using System.Threading.Tasks;
using GraphQL;
using Microsoft.AspNetCore.Mvc;
using Api.Graphql;

[Route("graphql")]
[ApiController]
public class GraphqlController: ControllerBase 
{
}
```

By using the decorator `Route` we are able to map a certain route to class instead of relying on a default convention. As you can see we give it the argument `graphql` to ensure it matches `/graphql`. We also give the class the decorator `ApiController`, this is something we need to do to all API Controllers so they can respond to requests.

Next, we need a method to handle requests. A good thing to know about GraphQL is that all requests in GraphQL use the verb `POST`, consequently, we need to set up such a method like so:

```csharp
[HttpPost]
public async Task<ActionResult> Post([FromBody] GraphQLQuery query) 
{
  return null;
}

```
The decorator `HttpPost` ensures that we can respond to `POST` requests. Let's have closer look at the input parameter `query`. It uses the decorator `FromBody` to parse out values from the posted Body and try to convert it to the type `GraphQLQuery`. 

Two questions come to mind, what is `GraphQLQuery` and why do we need it?

`GraphQLQuery` is a class we need to define so let's do that by creating `/Graphql/GraphQLQuery.cs`:

```csharp
using Newtonsoft.Json.Linq;

namespace Api.Graphql
{
  public class GraphQLQuery
  {
    public string OperationName { get; set; }
    public string NamedQuery { get; set; }
    public string Query { get; set; }
    public JObject Variables { get; set; }
  }
}
```

For the second question why we need it? It needs to look this way because we are integrating it with our visual environment GraphiQL. We have reason to come back to this structure once we start using GraphiQL and we can see how the above structure is populated. 

Let's add the rest of the implementation for our Controller:

```csharp
// GraphqlController.cs

using System.Threading.Tasks;
using Api.Graphql;
using GraphQL;
using Microsoft.AspNetCore.Mvc;

namespace graphql_ef.Controllers 
{
  [Route("graphql")]
  [ApiController]
  public class GraphqlController: ControllerBase 
  {
    [HttpPost]
    public async Task<ActionResult> Post([FromBody] GraphQLQuery query) 
    {
      var schema = new MySchema();
      var inputs = query.Variables.ToInputs();

      var result = await new DocumentExecuter().ExecuteAsync(_ =>
      {
        _.Schema = schema.GraphQLSchema;
        _.Query = query.Query;
        _.OperationName = query.OperationName;
        _.Inputs = inputs;
      });

      if (result.Errors?.Count > 0)
      {
        return BadRequest();
      }

      return Ok(result);
    }
  }
}
```

Above we are reading qhat we need from our input `query` and pass that on to the `DocumentExecuter` and we end up with a result. 


We have everything in place right now to try out our Api so let's do that next with `Debug/Start Debugging`. You should see the following:

![](https://thepracticaldev.s3.amazonaws.com/i/i0wo3u2rqo3i2ygovfhh.png)

Here we have created three queries `AllBooks`, `Author` and `AllBooksWithAuthor`.  

We can easily run one of the queries hitting the `Play` button, this allows us to select a specific one:

![](https://thepracticaldev.s3.amazonaws.com/i/woczpm9wbi4qzk8dfk3w.png)

Running the query we get the following back:

![](https://thepracticaldev.s3.amazonaws.com/i/wxs4se3dqkj2mbwvbr67.png)

We aren't surprised though as we have only stubbed out the answer to return an empty array. Before we fix that and connect with a database let's talk a bit more about our GraphiQL environment.

One great thing I failed to mention was that we have auto-complete support when author our query or mutation so we can easily get info as we type what resources and columns are available:

![](https://thepracticaldev.s3.amazonaws.com/i/3wy429n4zzfry41mf3br.png)

We can obviously write a number of queries and select the one we want. There is more, we can look the right pane and see that our schema definition can be browsed:

![](https://thepracticaldev.s3.amazonaws.com/i/jue75s6vvbmnvvl3ckvs.png)

Clicking the `Docs` link will show all the types we have starting with the top-level:

![](https://thepracticaldev.s3.amazonaws.com/i/8duehqxhdrjxhwsn3swa.png)

Then we can drill down as much as we want and see what we can query for, what custom types we have and more:

![](https://thepracticaldev.s3.amazonaws.com/i/0acor4xa2fr8dd47pcq4.png)


## Adding a database with Entity Framework

Now that we have everything working, let's define the database and replace the stubbed answers in the resolver methods with database calls. 

To accomplish all this we will do the following:

1. **Define a database in code**, We do this by creating a class inheriting from `DbContext` and ensure it has fields in it of type `DbSet`
2. **Define the models** we mean to use in the Database, we've actually already done this step when we created `Author` and `Book`.
3. **Set up and configure** the database type, we will use an in-memory database type for this but we can definitely change this later to Sql Server or MySql or whatever database type we need
4. **Seed the database**, for the sake of this example we want some initial data so that when we query we get something back 
5. **Replace the stubbed code** in resolver methods with real calls to the database 

### Define a database in code

We are using an approach called *code first*. This simply means we create a class with fields, where the fields become the tables in the Database. Let's create a file `StoreContext.cs` and give it the following content:

```csharp
using Microsoft.EntityFrameworkCore;

namespace Api.Database
{

  public class StoreContext : DbContext
  {
    public StoreContext(){}
    public StoreContext(DbContextOptions<StoreContext> options)
      : base(options)
    { }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
      optionsBuilder.UseInMemoryDatabase("BooksDb");
    }

    public DbSet<Book> Books { get; set; }
    public DbSet<Author> Authors { get; set; }
  }
}
```

The two fields `Books` and `Authors` is of type `DbSet<Book>` and `DbSet<Author>` respectively and will become tables in our database. The method `OnConfiguring()` is where we set up our database `BooksDb` and we also specify that we want to make it in an in-memory database with the method `UseInMemoryDatabase()`. We can change this to something else should we want it to persist an actual database. 

### Seed the database

Now this is not a step we must do but it's nice to have some data when we start querying. For this we will open up `Program.cs` and add the following to the `Main()` method:

```csharp

using(var db = new StoreContext()) 
{
    var authorDbEntry = db.Authors.Add(
        new Author
        {
            Name = "Stephen King",
        }
    );

    db.SaveChanges();

    db.Books.AddRange(
    new Book
    {
        Name = "IT",
        Published = true,
        AuthorId = authorDbEntry.Entity.Id,
        Genre = "Mystery"
    },
    new Book
    {
        Name = "The Langoleers",
        Published = true,
        AuthorId = authorDbEntry.Entity.Id,
        Genre = "Mystery"
    }
    );

    db.SaveChanges();
}
```

The above will create an author and two books.

### Replace the stubbed code

Now to the fun part. We will replace our stubbed code with actual calls to the database and Entity Framework. 

There are two files we need to change, `Query.cs` and `Mutation.cs`. Let's start with `Query.cs`.

**Query.cs**

Open up the file `Query.cs` under the Graphql directory and replace its content with the following:

```csharp
// Graphql/Query.cs

using System.Collections.Generic;
using GraphQL;
using System.Linq;
using Api.Database;
using Microsoft.EntityFrameworkCore;

namespace Api.Graphql 
{
  public class Query
  {

    [GraphQLMetadata("books")]
    public IEnumerable<Book> GetBooks()
    {
      using(var db = new StoreContext())
      {
        return db.Books
        .Include(b => b.Author)
        .ToList();
      }
    }

    [GraphQLMetadata("authors")]
    public IEnumerable<Author> GetAuthors() 
    {
      using (var db = new StoreContext())
      {
        return db.Authors
        .Include(a => a.Books)
        .ToList();
      }
    }

    [GraphQLMetadata("author")]
    public Author GetAuthor(int id)
    {
      using (var db = new StoreContext())
      {
        return db.Authors
        .Include(a => a.Books)
        .SingleOrDefault(a => a.Id == id);
      }
    }

    [GraphQLMetadata("hello")]
    public string GetHello()
    {
      return "World";
    }
  }
}
```

Above we have replaced all our stubbed code with calls to the Database. Let's go through the relevant methods:

**GetBooks**

```csharp
[GraphQLMetadata("books")]
public IEnumerable<Book> GetBooks()
{
  using(var db = new StoreContext())
  {
    return db.Books
    .Include(b => b.Author)
    .ToList();
  }
}
```

Above we are selecting all the Books from the database and also ensuring we include the `Author` property. This is so we support a query like:

```
{
  books {
    name,
    author {
      name
    }
  }
}
```

**GetAuthors**

```csharp
[GraphQLMetadata("authors")]
public IEnumerable<Author> GetAuthors() 
{
  using (var db = new StoreContext())
  {
    return db.Authors
    .Include(a => a.Books)
    .ToList();
  }
}
```

Here we are selecting all the Authors from the database and we also include all the books written by that author. This is so we support a query like so:

```csharp
{
  authors {
    name,
    books {
      name,
      published
    }
  }
}
```

**Mutation.cs**

Open up `Mutation.cs` and replace its stubbed code with:

```csharp
using Api.Database;
using GraphQL;

namespace Api.Graphql 
{
  [GraphQLMetadata("Mutation")]
  public class Mutation 
  {
    [GraphQLMetadata("addAuthor")]
    public Author Add(string name)
    {
      using(var db = new StoreContext()) 
      {
        var author = new Author(){ Name = name };
        db.Authors.Add(author);
        db.SaveChanges();
        return author;
      }
    }
  }
}
```

As you can see above we support the mutation `addAuthor(name: String): Author` by creating a new author, save it to the database and then returning the entity.

**Test it out in GraphiQL**

We have one last thing to do namely to test this out in our visual interface. Hit `Debug/Start Debugging` and let's see what happens:

![](https://thepracticaldev.s3.amazonaws.com/i/emrxedu66t6trcrvy0i9.png)

It seems like our query to list books work fine, it gives us the titles from the database.

Next, let's try to carry out a mutation:

![](https://thepracticaldev.s3.amazonaws.com/i/qch5h4jstjayqgu54zst.png)

Judging from the above result that seems to have gone well, awesome! :)

## Summary

This was quite an ambitious article. We managed to create a GraphQl Api within a Web Api. We also managed to involve a database that we accessed with Entity Framework. 

The big takeaway from this was not only how easy this was to set up but the wonderful visual environment GraphiQL.  It not only helped us with auto-completion but documented our schema, helped us verify our queries and more.

Hope you found this useful albeit a somewhat long read.

As a final comment, I would like to say that `webapi` project type comes with built-in Dependency Injection that I was unable to use. The main reason was that this way of setting up GraphQL meant that we weren't in control of instantiating `Query` and `Mutation`. You can see in the references section how I point to an article doing what we did here today and managed to use DI. However, you have to set up your GraphQL schema in a very different way, that IMO is much more verbose.