How you can build a Serverless API using GraphQL .Net Core, C# and VS Code
Tags: dotnet, serverless, webdev, tutorial
Published: 2019-08-07 15:30:53

---
title: How you can build a Serverless API using GraphQL .Net Core, C# and VS Code
published: true
description: This shows how you can create a CRUD API in GraphQL and host it in a Serverless function
tags: dotnet, serverless, webdev, tutorial
cover_image: https://thepracticaldev.s3.amazonaws.com/i/3fh654kg74d0ii58chs9.jpg
canonical_url: https://softchris.github.io/pages/dotnet-graphql-serverless.html
---

Follow me on [Twitter](https://twitter.com/chris_noring), happy to take your suggestions on topics or improvements /Chris

> This article takes you through how to build a full CRUD API using GraphQL. We end up hosting it in a Serverless function and also show how you can do external HTTP calls to build your API. Whether the data lives here or somewhere else doesn't matter. GraphQL is the front that your users will talk to.

TLDR; This article might be a bit long but it does teach a lot on GraphQL, queries, mutations. It also teaches you how to create a serverless function all in the context of .Net Core, C# and VS Code

In this article we will:

- **Learn** how to build a full CRUD GraphQL including queries and mutations
- **Create** a Serverless function and Host our GraphQL API in a function
- **Show** how you can make an external HTTP call and make that part of our GraphQL API

## Resources

- [Getting started with GraphQL in .Net](https://dev.to/dotnet/learn-how-you-can-use-graphql-in-net-core-and-c-4h96?wt.mc_id=devto-blog-chnoring)
This is the first article I've written on the topic of GraphQL with .Net. I recommend you have a look to get a feeling for the basics of GraphQL. 

- [GraphQL](https://graphql.org/)

- [Starting with Azure Functions](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-vs-code?wt.mc_id=devto-blog-chnoring)
Covers creating a Serverless function and deploying to the Cloud using VS Code

- [Starting with Serverless in .Net](https://docs.microsoft.com/azure/azure-functions/functions-dotnet-class-library?wt.mc_id=devto-blog-chnoring)
.Net C# Developer reference to Azure Functions

- [Creating a Serverless API in C# and .Net](https://dev.to/azure/how-you-can-create-a-serverless-api-in-c-and-net-1ie?wt.mc_id=devto-blog-chnoring)
Article I wrote covering how to create a CRUD API with Serverless, .Net, C#, and VS Code

- [Create your first Serverless function](https://docs.microsoft.com/learn/modules/create-serverless-logic-with-azure-functions/?wt.mc_id=devto-blog-chnoring)
LEARN module for creating an Azure Function

- [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)



##  Create a Serverless function app

The first thing we will do is to create a Serverless function. But what is Serverless and why might it be useful in the context of GraphQL? That's really two questions but let's try to answer them in order.

### Why Serverless? 

Serverless is not about *no servers* but more about the server is NOT in your basement, anymore. In short, the servers have moved to the Cloud. That's not all, however. *Serverless* have come to mean other things namely that everything is set up for you. That means you don't need to think about what OS your code runs on or what Web Server runs it, everything is *managed*. There is more.

> There is always more, isn't it? What now a fancy sticker?

It's about cost. Serverless usually means it's cheap.

> Why is it cheap?

Well, Serverless code is meant to be run seldom and you are only billed for the time it executes

> Ok, how do YOU make money?

Well, the function isn't always there. Whatever resources are needed are allocated when someone/something queries your function.

> Doesn't that make it a bit slow like there could be some initial wait when it's scrambling to be created and then respond the query?

You are right. This is something called a *cold start*. This can be avoided however by either regularly polling our function or using a premium offering that shortens the *cold start*. 

> Ok so it's I can either have 100% availability or cheap, pick one :)

I guess so.


### Why Serverless with GraphQL?

Ok, we are a bit smarter about the *whats* and *whys* of Serverless so why add GraphQL to the mix?

Well, GraphQL has the ability to stitch together data from different APIs so it could act as an API that aggregates data from different sources. So in a sense, it works well in the context of Serverless cause it's not like you need to have any data stored in the function if it's someone else's API.

> Ok sounds good, I guess there are no other good reasons the rest is just about the hype that's GraphQL and Serverless right? ;)

...


### Prerequisits

To create a Serverless function we first need a function app to put it in. To makes this as easy as possible we will be using VS Code and an Azure Function extension. So our prerequisites are:

1. Node.js
2. Visual Studio Code
3. Azure Functions extension

We can download Node.js from the following page:

> https://nodejs.org/en/

You can find Visual Studio code here:

> https://code.visualstudio.com/download

As for the extension we need. Search for an extension called `Azure Functions`. It should look like the below:

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

### Scaffold

Ok, now we should be all setup and ready to create our first Serverless function. As mentioned before, the function needs to live within something called a function app. So we need to create the function app first.

Hit `CMD+SHIFT+P` or choose `View/Command Palette` to bring up the command palette:

Now we need to type a command that will help us create a Serverless function app. It's called `Azure Functions: Create New Project`

Then it's going to ask you for what directory to create the app. The directory you are standing in is the default chosen one, select that. 

Next thing it asks about is the language, select `C#`. 

Next up it's asking you about the projects first function and how it should be triggered. Select `HttpTrigger`. 

Now you need to provide a function name. Call it Graphql. 

Next question is a namespace. You could really choose anything here but let's call it `Function` just for the sake of it. 

Lastly, it asks about `Access Right`. There are different options here `Anonymous`, `Function`, `Admin`. We select `Anonymous` as we want to make our function publically available. The other options mean we would need to provide some kind of key when calling the function. 

VS Code should now scaffold all the needed files. It should also ask you to `restore` all dependencies, to download the libraries. You could also run 

```
dotnet restore
```

if you should miss clicking on this dialog.

Your project structure should now look like this:

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

### Test it out

Let's ensure that we can run our newly scaffolded function. First, you should have been prompted if you want to add the necessary to be able to debug. You should answer `YES` here. This will generate a directory `.vscode` looking like the below:

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

The `tasks.json` contains tasks needed to build, clean and run your project. These will assist you with the step we are about to do next `Debugging`. 

To Debug we choose `Debug/Start Debugging` from the menu. It should compile the code and once done it should look like this:

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

It's telling us to go to `http://localhost:7071/api/Graphql`

Let's spin up a browser:

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

Seems to work alright. :) 

It's hitting our function `Graphql`. Speaking of which, let's have a quick look at the sample code we've been given when we scaffolded the Serverless app:

```csharp
// Graphql.cs

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Function
{
    public static class Graphql
    {
        [FunctionName("Graphql")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}
```

Let's not spend to much time understanding everything right now but suffice to say it does its job and is able to work with query parameters:

```csharp
string name = req.Query["name"];
```

and the Body, in case you POST a request:

```csharp
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
```

Next, let's talk GraphQL.

## Adding GraphQL to Serverless

Ok, we established that we wanted to add GraphQL to our Serverless function. First, let's build a GraphQL API. Any GraphQL will contain the same moving parts:

- **A Schema**, this will define what we can query for and what custom data types we have
- **A Resolver**, a collection of functions that is able to respond to a request and ends up delivering a response

### Adding a GraphQL schema

This will be authored in something called GQL or **G**raphQL **Q**uery **L**anguage. Our schema will look like the following:

```gql
type Jedi {
  id: ID
  name: String,
  side: String
}

input JediInput {
  name: String
  side: String
  id: ID
}

type Mutation {
  addJedi(input: JediInput): Jedi
  updateJedi(input: JediInput ): Jedi
  removeJedi(id: ID): String
}

type Query {
    jedis: [Jedi]
    jedi(id: ID): Jedi
    hello: String
}
```

Now that's a lot. Let's explain what we are looking at. 

**Query**

Anything of type `Query` or `Mutation` is something we can ask for in our query to our API. The semantic meaning of `Query` is that you want to *fetch* data. In this case, we want to fetch a list of jedis using a query syntax like this:

```
{
  jedis { name side }
}
```

This is equivalent to writing the following in SQL:

```
SELECT name, side
FROM jedis;
```

The other thing we do is supporting a query with a parameter, namely `jedi(id: ID): Jedi`. We call it like so:

```
{ 
  jedi(id: 1) { name }
}
```

This is equivalent to writing the following in SQL:

```
SELECT name
FROM jedi
WHERE id=1;
```

**Custom types**

Everything queryable was defined under `type Query`. Everything else except for `type Mutation` are custom types that we define. For example:

```
type Jedi {
  id: ID
  name: String,
  side: String
}
```

**Mutation**

This semantically means we will try to change the data. Looking at the operations we support:

```
addJedi(input: JediInput): Jedi
updateJedi(input: JediInput ): Jedi
removeJedi(id: ID): String
```

We can see that we support adding, updating and removal. 

To call a mutation we need to type like so:

```
mutation test { 
  addJedi(input: { 
    name: "JarJar", 
    side: "Dark"  
  }) { name } 
}
```

**Input, complex input for our Mutation**

Note the input property `input` in `addJedi()`. If we look at the schema we can see that it's of type `JediInput` which is defined like this:

```
input JediInput {
  name: String
  side: String
  id: ID
}
```

The reason we are using the keyword `input` instead of `type` is that this is a special case. Special how, you wonder? Well, there are two types of input parameters to a mutation:

1. **Scalars**, this is a String, ID, Boolean, etc, also called primitives
2. **Inputs**, this is nothing more than a complex data type with many properties on it, example `JediInput`

so it's definitely possible to define a mutation looking like this:

```
type Mutation {
  addTodo(todo: String!): String
}
```

So the million-dollar question is why can't I just use a custom type like `Jedi` as an input parameter type to my mutation? 

> The honest answer is I don't know. 

Just remember this: If you need an input parameter that is more complex than a scalar, then you need to define it like so:

```
input MyInputType {
  // my columns
}
```

**Add NuGet package**

Ok next step is to set up this schema properly in code. For that we will create a file `Server.cs` and also install the GraphQL package like so:

```
dotnet add package GraphQL 
```

**Create a Schema**

Now add the following code to `Server.cs`, like so:

```csharp
using GraphQL;
using GraphQL.Types;
using Newtonsoft.Json;
using System.Threading.Tasks;

namespace Function {
  public class Server 
  {
    private ISchema schema { get; set; }
    public Server() 
    {
      this.schema = Schema.For(@"
          type Jedi {
            id: ID
            name: String,
            side: String
          }

          input JediInput {
            name: String
            side: String
            id: ID
          }

          type Mutation {
            addJedi(input: JediInput): Jedi
            updateJedi(input: JediInput ): Jedi
            removeJedi(id: ID): String
          }

          type Query {
              jedis: [Jedi]
              jedi(id: ID): Jedi
          }
      ", _ =>
      {
        _.Types.Include<Query>();
        _.Types.Include<Mutation>();
      });

    }

    public async Task<string> QueryAsync(string query) 
    {
      var result = await new DocumentExecuter().ExecuteAsync(_ =>
      {
        _.Schema = schema;
        _.Query = query;
      });

      if(result.Errors != null) {
        return result.Errors[0].Message;
      } else {
        return JsonConvert.SerializeObject(result.Data);
      }
    }
  }
}
```

In the constructor above we set up the Schema by calling `Schema.For()` with a string representing our schema expressed as GQL. The second argument of that won't compile though, namely this part:

```csharp
_ =>
  {
    _.Types.Include<Query>();
    _.Types.Include<Mutation>();
  }
```

### Adding resolvers

The reason is it won't compile is that `Query` and `Mutation` don't exist yet. They are simply resolver classes answering to query and mutation requests. Let's make it compile by creating first `Db.cs` and a file `Query.cs`

**Adding in-memory database**

```csharp
// Db.cs

using System.Collections.Generic;
using System.Linq;

namespace Function
{
  public class StarWarsDB
  {
    private static List<Jedi> jedis = new List<Jedi>() {
      new Jedi(){ Id = 1, Name ="Luke", Side="Light"},
      new Jedi(){ Id = 2, Name ="Yoda", Side="Light"},
      new Jedi(){ Id = 3, Name ="Darth Vader", Side="Dark"}
    };
    public static IEnumerable<Jedi> GetJedis()
    {
      return jedis;
    }

    public static Jedi AddJedi(Jedi jedi)
    {
      jedi.Id = jedis.Count + 1;
      jedis.Add(jedi);
      return jedi;
    }

    public static Jedi UpdateJedi(Jedi jedi)
    {
      var toUpdate = jedis.SingleOrDefault(j => j.Id == jedi.Id);
      toUpdate.Name = jedi.Name;
      toUpdate.Side = jedi.Side;
      return toUpdate;
    }

    public static string RemoveJedi(int id)
    {
      var toRemove = jedis.SingleOrDefault(j => j.Id == id);
      jedis.Remove(toRemove);
      return "success";
    }
  }

  public class Jedi
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Side { get; set; }
  }
}

```

`Db.cs` is nothing more than a simple in-memory database. 

**Adding a  resolver class to handle all Queries**

Next, let's create `Query.cs`:

```csharp
// Query.cs

using System.Collections.Generic;
using GraphQL;
using System.Linq;

namespace Function
{
  public class Query
  {
    [GraphQLMetadata("jedis")]
    public IEnumerable<Jedi> GetJedis()
    {
      return StarWarsDB.GetJedis();
    }

    [GraphQLMetadata("jedi")]
    public Jedi GetJedi(int id)
    {
      return StarWarsDB.GetJedis().SingleOrDefault(j => j.Id == id);
    }

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

}
```

What's interesting about the above is how we map something in our GraphQL schema to a resolver function. For that we use the decorator `GraphQLMetadata` like so:

```csharp
[GraphQLMetadata("jedis")]
public IEnumerable<Jedi> GetJedis()
{
  return StarWarsDB.GetJedis();
}
```

The above tells us that if the user queries for `jedis` then the function `GetJedis()` will respond. 

Dealing with parameters is almost as easy. It's the same decorator but we just add input parameter like so:

```csharp
[GraphQLMetadata("jedi")]
public Jedi GetJedi(int id)
{
  return StarWarsDB.GetJedis().SingleOrDefault(j => j.Id == id);
}
```

**Adding a  resolver class to handle all Mutation requests**

We are almost there but we need the class `Mutation.cs` and let's add the following content to it:

```csharp
// Mutation.cs

using GraphQL;

namespace Function {
  public class Mutation
  {
    [GraphQLMetadata("addJedi")]
    public Jedi AddJedi(Jedi  input) 
    {
      return StarWarsDB.AddJedi(input);
    }

    [GraphQLMetadata("updateJedi")]
    public Jedi UpdateJedi(Jedi input)
    {
      return StarWarsDB.AddJedi(input);
    }

    [GraphQLMetadata("removeJedi")]
    public string AddJedi(int id)
    {
      return StarWarsDB.RemoveJedi(id);
    }
  }
}
```

As you can see it looks very similar to `Query.cs`, even with parameter handling.

**Updating our Serverless function**

There's just one piece left of the puzzle, namely our serverless function. It needs to be altered so we can support the user to invoke our function like so:

```
url?query={ jedis } { name }
```

Change the code in `Graphql.cs` to the following:

```csharp

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Function
{
    public static class GraphQL
    {
        [FunctionName("GraphQL")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var server = new Server();
            string query = req.Query["query"];
            // string query = "mutation test { addJedi(input: { name: \"JarJar\", side: \"Dark\"  }) { name } }";

            var json = await server.QueryAsync(query);
            return new OkObjectResult(json);
        }
    }
}


```

### Test it all out

To test it we just start debugging by choosing `Debug/Start Debugging` from the menu and change the URL in the browser to:

```
http://localhost:7071/api/GraphQL?query={ jedis { name } }
```

Let's see what the browser says:

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

![](https://thepracticaldev.s3.amazonaws.com/i/76xk54ulkvlggtgsrq8b.gif)

Yep, we did it. Serverless function with a GraphQL API.

## Bonus - calling other endpoints

Now. One of the great things about GraphQL is that it allows us to call other APIs and thereby GraphQL acts as an aggregation layer. We can easily achieve that by the following steps:

1. **Do the HTTP request**, this should do the request to our external API
2. **Add  resolver method** for our *external* call
3. **Update our schema** with the new type
4. **Test** it out

### HTTP Request

We can easily do HTTP request in .Net with `HttpClient` so let's create a class `Fetch.cs` like so:

```csharp
// Fetch.cs

using System.Net.Http;
using System.Threading.Tasks;

namespace Function {
  public class Fetch
  {
    private static string BaseUrl = "https://swapi.co/api";
    public static async Task<string> ByUrl(string url)
    {
      using (var client = new HttpClient())
      {
        var json = await client.GetStringAsync(string.Format("{0}/{1}", BaseUrl, url));

        return json;
      }
    }
  }
}
```

### Add resolver method

Now open up `Query.cs` and add the following method to the `Query` class:

```csharp
[GraphQLMetadata("planets")]
  public async Task<List<Planet>> GetPlanet() 
  {
    var planets = await Fetch.ByUrl("planets/");
    var result = JsonConvert.DeserializeObject<Result<List<Planet>>>(planets);
    return result.results;
  }
```

Additionally, we should be installing a new NuGet package:

```
dotnet add package Newtonsoft.Json
```

This is needed so we can convert the JSON response we get into a Poco.

We should also add types `Planet` and `Result` to `Query.cs`, but outside the class definition:

```csharp
public class Result<T>
{
  public int count { get; set; }
  public T results { get; set; }
}

public class Planet
{
  public string name { get; set; }
}
```

### Update our schema with the new type

We have the schema left to update before we can try it out. So let's open up `Schema.cs` and make sure it now looks like this:

```csharp
this.schema = Schema.For(@"
          type Planet {
            name: String
          }

          type Jedi {
            id: ID
            name: String,
            side: String
          }

          input JediInput {
            name: String
            side: String
            id: ID
          }

          type Mutation {
            addJedi(input: JediInput): Jedi
            updateJedi(input: JediInput ): Jedi
            removeJedi(id: ID): String
          }

          type Query {
              jedis: [Jedi]
              jedi(id: ID): Jedi
              hello: String
              planets: [Planet]
          }
      ", _ =>
      {
        _.Types.Include<Query>();
        _.Types.Include<Mutation>();
      });
```

Above we've added the type `Planet`:

```
type Planet {
  name: String
}
```

We've also added `planets` to `Query`:

```
planets: [Planet]
```

### Testing it out

That should be it, let's test it. `Debug/Start Debugging`:

```
http://localhost:7071/api/GraphQL?query={ planets { name } }
```

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

There we have it. :) 

We've managed to do an external call to an API and make that part of our GraphQL API. As you can see we can intermix data from different sources easily.

## Summary

We've managed to create a GraphQL that supports the full CRUD. That is we support both querying for data but also creating, update and delete.

Additionally, we've taken our first steps with Serverless functions. 

Finally, we added our GraphQL API to be served by our Serverless function.

As an added bonus we also showed how we could take to external APIs and make them part of our API. That's really powerful stuff.

I hope you enjoyed this article. In out next part we will take a look at how to add GraphQL to a Web API project in .Net Core.