HotChocolate: Introduction to GraphQL for ASP.NET Core (Part 1)
Tags: graphql, netcore, hotchocolate
Published: 2021-01-04 10:38:07

In this post, I will walk you through how to get started with GraphQL in ASP.NET Core using HotChocolate.
In this part, we will only focus on GraphQL Server, configuring it with ASP.NET Core. 
In [part 2](https://dev.to/jioophoenix/consuming-graphql-api-in-asp-net-core-part-2-55ga), We will focus on integrating the GraphQL endpoint into a Blazor WebAssembly application.

##Introduction

[GraphQL](https://graphql.org/learn/) is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. It lets you specify exactly what data you need.

*[HotChocolate](https://github.com/ChilliCream/hotchocolate-docs/tree/master/docs) is a .NET GraphQL platform that can help you build a GraphQL layer over your existing and new application. HotChocolate is very easy to set up and takes the clutter away from writing GraphQL schemas.*

We will create a simple application that can be used to **Create**, **Read**, **Update** and **Delete** an Employee together with a department. 

The code for this sample can be found on the [CloudBloq/GraphQLSampleApp](https://github.com/CloudBloq/GraphQLSampleApp) repository on GitHub.


##Prerequisites

* [Visual Studio 2019 (version 16.8.0 upwards)](https://visualstudio.microsoft.com/vs/)
* [SQL Server 2019](https://www.microsoft.com/en-us/sql-server/sql-server-downloads)

##The Database

The database schema and data script can be found in the folder [CloudBloq/GraphQLSampleApp/tree/master/GraphQLSampleApp/Script](https://github.com/CloudBloq/GraphQLSampleApp/tree/master/GraphQLSampleApp/Script). Ensure to run the script in [SQL Server Management Studio](https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15) or in Visual Studio **SQL Server Object Explore** to set up the Database and tables.


##Create the Solution and Project

We will need an ASP.NET Web API project. After opening VS, click the **Create a new project** link and select the **ASP.NET Core Web Application**, give the project a name **GraphQLSampleApp** and the solution a name **GraphQLSampleApp** click **Create**. Next, select the **API**, then click **Create**.


##Install Dependencies

* We need to install the [HotChocolate.AspNetCore(v11.0.2)](https://chillicream.com/) package. The package contains the GraphQL API's for ASP.NET. To install the package, right click the solution in the solution explorer and select **Manage NuGet Packages for Solution**. Under the Browse section, search for **HotChocolate.AspNetCore** and click on it, then in the preview panel click the Install button:
![nugetpackage](https://dev-to-uploads.s3.amazonaws.com/i/ijcahpsnsstnmjev93wi.jpg)

* Also, install the **Microsoft.EntityFrameworkCore**, **Microsoft.EntityFrameworkCore.SqlServer** and **Microsoft.EntityFrameworkCore.Tools** packages respectively.




##The Entities

We will make use of [EntityFrameworkCore](https://www.entityframeworktutorial.net/efcore/entity-framework-core.aspx) as the ORM. Entities (classes) are used to define the database objects (tables) and those entities are mapped to the database table in the [DbContext](https://www.entityframeworktutorial.net/efcore/entity-framework-core-dbcontext.aspx).  

We will define two Entities, one for the **Department** and the other for the **Employee** tables.
We will keep everything simple by using folders to hold the data access code, the GraphQL code and the Database Entities. In a real application, a Class library would be better for the different layers.

Create a folder called **DataAccess** in the **GraphQLSampleApp** project, create another folder called **Entity** inside the **DataAccess** folder. 

###Department Entity

Add a C# Class file called **Department.cs** to the **Entity** folder. This class will be used to define the **Department** entity. The code for this file is:

{% gist https://gist.github.com/JIOO-phoeNIX/0e373fb3981c39624293df25f7ae9be9 %}

Line 9 is used to mark the DepartmentId property as the primary key of the entity, line 10 is used to ensure that the value of the DepartmentId is unique and auto generated if it is not provided by the user. Line 15 is used to define a relationship (navigation property) between the Department and Employee entity. The relationship:

```csharp
public ICollection<Employee> Employees { get; set; }
```
means that a single Department can have many Employees assigned to it. This line will throw an error now unless you have created the Employee entity earlier.

###Employee Entity

Add another C# class to the **Entity** folder called **Employee.cs**. After adding this class, the error gotten earlier in **Department.cs** will no longer be there. The code for this file is:

{% gist https://gist.github.com/JIOO-phoeNIX/34d2a35ef1c8410f2eaa6013065ba565 %}

Line 24 defines the foreign key property used to link an Employee to his/her department. Line 25 defines the navigation property that states that an Employee can only have one department. 

###The DbContext

The DbContext will be simple and straight forward. In a real application, most of the database configurations are done in this file. Add a new C# Class file to the **Entity** folder, name it **SampleAppDbContext.cs**. The code for this file is:

{% gist https://gist.github.com/JIOO-phoeNIX/627b0f130a760f3013490eb54ba9f8f1 %}

Line 11 defines the Employee property which is used to map the Employee.cs entity to the Employee table in the database. Line 13 defines the Department property which is used to map the Department.cs entity to the Department table in the database.


##Repositories

Next, we will write the layer that will send and receive data to and from the database. In the **DataAccess** folder, add another folder called **DAO**.

###Department Repository

Add a C# class file called **DepartmentRepository.cs** to the **DAO** folder:

{% gist https://gist.github.com/JIOO-phoeNIX/f31ef9d7e85b08ebbb2f596a84bdbb50 %}

Lines 19 to 22 define the GetAllDepartmentOnly() method which is used to return a list of all the Departments.
Lines 24 to 29 define the GetAllDepartmentsWithEmployee() method which returns all the Departments along-side the Employee(s) in each Department. The navigation property defined in line 15 in **Department.cs** made it possible to return the Departments along-side the Employee(s).
Lines 31 to 36 define the CreateDepartment() method which takes in a new Department and adds it to the database.

###Employee Repository

Add a C# class file called **EmployeeRepository.cs** to the **DAO** folder:
 
{% gist https://gist.github.com/JIOO-phoeNIX/aa7823d55e832cf505ad3f4956de8bed %}

This class defines the GetEmployees() which returns a list of all the Employees, the GetEmployeeById() which takes an Id and returns the Employee only if the Id is valid and exists, the GetEmployeesWithDepartment() which returns a list of all the Employees along-side the Department, and the CreateEmployee() which takes in an Employee and adds them to the database.


## GraphQL 

If you are familiar with REST API, we use GET to fetch data from the data store, we use POST, PUT DELETE to modify the state of data. GET in REST API is same as Query in GraphQL. POST, PUT, DELETE, is same as Mutation. In GraphQL, there is also Subscription which is used to set up event listeners.

### Query

Add a new C# class file called **Query.cs** to the **DataAccess** folder. This class will contain all the Queries we need to perform:

{% gist https://gist.github.com/JIOO-phoeNIX/7c5d218da5c4a2ffc4a591b883d62111 %}

AllEmployeeOnly() on line 12 returns all the Employees; we inject an instance of the **EmployeeRepository** into this method by marking the input parameter with the [Service] attribute. AllEmployeeWithDepartment() on line 15 returns the Employees along-side the Department.
Line 18 defines GetEmployeeById(), the parameter **ITopicEventSender eventSender** is used to create a subscription with Topic "ReturnedEmployee". Anytime this method is called, the event is sent on line 22 and any method that subscribes to this event will receive the data.


### Mutation

Add a new C# class file called **Mutation.cs** to the **DataAccess** folder. This class will contain all the Mutations we need to perform:

{% gist https://gist.github.com/JIOO-phoeNIX/8d519a08f8d66d14a87e5f9e1db8b431 %}

Line 15 defines CreateDepartment(). The parameter departmentName will be provided by the user. The parameter ITopicEventSender eventSender is used to create a subscription with Topic "DepartmentCreated".

Line 29 defines a method CreateEmployeeWithDepartmentId() that can be used to create a new Employee passing in an existing DepartmentId i.e. create an Employee with an existing department. The parameters name: string, age: int, email: string, and departmentId: int will be provided by the user. Notice we set the DepartmentId on line 37 to the departmentId passed by the user.

Line 44 defines CreateEmployeeWithDepartment(). This method is used to create a new Employee. In the process of creating the Employee, a new Department is created and the DepartmentId property of this Employee is set automatically to the DepartmentId of the newly created Department. Notice how this is done on line 52 by setting the navigation property to a new Department.


### Subscription

Subscriptions are used to set up event listeners e.g. we can set up an event listener that responds when we create a new Department or Query the database for an Employee etc. Add a new C# class file called **Subscription.cs** to the **DataAccess** folder:

{% gist https://gist.github.com/JIOO-phoeNIX/a0e5f4e7dee988ce74c405c4a3582b3b %}

OnDepartmentCreate() on line 17 defines a subscriber of Topic "DepartmentCreated" likewise line 25 defines OnEmployeeGet() a subscriber of Topic "ReturnedEmployee". 


##Configuring GraphQL

We need to configure the application to make use of GraphQL. Replace the code in your Startup.cs with:

{% gist https://gist.github.com/JIOO-phoeNIX/6f9510b6b5d95f4fa90bbc139e1119c2 %}

Line 32 is used to add the Service for GraphQL, Query, Mutation and Subscription. The AddQueryType(), AddMutationType() and AddSubscriptionType() takes in the Query, Mutation and Subscription classes respectively. 

Line 55 is used to map the endpoint to use GraphQL. 
The middleware on line 50 is used to configure the application to ensure the Subscription gives the output. 

Line 27 adds the DbContext service; we configure this service to make use of SQL Server as the database. The connection string is defined in the **appsettings.json** file as:

{% gist https://gist.github.com/JIOO-phoeNIX/0e5b9d8a32b3d93bb44c3bc5895c87dd %}

Don't forget to change the **Data Source** value to that of the database you ran the schema and data script in.


##Running the Application

Right-click the solution and click Build Solution. After Build is successful, click CTRL + f5 or f5 to run the application. In your browser, navigate to [https://localhost:44351/graphql/](https://localhost:44351/graphql/), you should get 

![runtime](https://dev-to-uploads.s3.amazonaws.com/i/gxv8b02f0vnl89wrt7eq.jpg)
 
HotChocolate gives you a GraphQL IDE (Banana Cake Pop) right in your browser out of the box, you don't need to install any GraphQL IDE. 

The methods defined in Query.cs, Mutation.cs and Subscription.cs have been categorized under Query, Mutation and Subscription respectively.

###Test Query
In Banana cake pop, you can add a new tab by clicking the **+** in the top right corner of the IDE. You can run your schema by clicking the Execute/Play button in the top right corner. Add and run:
```graphql
query{
  allDepartmentsWithEmployee{
    name
    employees{
      email
      name
    }
  }
}
```

You should get the response in the image below:
![query1](https://dev-to-uploads.s3.amazonaws.com/i/tk22fw10ac0f6zndglau.jpg).

Try out other Query types, defining the Schema of the data you need.


###Test Subscription and Query

Add and run the schema below:

```graphql
subscription{
  onEmployeeGet{
    name
    departmentId
    department{
      name    
    }
  }
}
```
![sub1](https://dev-to-uploads.s3.amazonaws.com/i/1roafldtjlgy2ic13fdt.jpg)

This Subscribes to the event "ReturnedEmployee" in line 28 of Subscription.cs. You won't get any output yet as shown in the image above, but you can see from the console that we have Subscribed to the event.

Launch [https://localhost:44351/graphql/](https://localhost:44351/graphql/) in another browser tab. Next, we will run a Query that will trigger the event. Add and run the below in a new Banana Cake Pop tab in the new browser tab:

```graphql
query{
  employeeById(id: 5){
    name
    email
  }
}
```
![query22](https://dev-to-uploads.s3.amazonaws.com/i/e7fczyncnti04yw1keav.jpg)

If you go back to the first browser tab where we subscribed to the event, you will get the response
![query3](https://dev-to-uploads.s3.amazonaws.com/i/h796nwzq6m7fjqlk9yt9.jpg)
If you change the value of the id and run the Query, you will see the changes in the Subscription.

###Test Mutation 

Add and run the schema below:

```graphql
mutation{
  createEmployeeWithDepartment(name: "newemp", age: 30,
  email: "newemp@gmail.com", departmentName: "Mechanical Engr"){
    departmentId
    name
    department{
      departmentId
      name     
    }
  }
}
```

You would get

![mutation](https://dev-to-uploads.s3.amazonaws.com/i/fkrzgqj203z8pdcqi2l4.jpg)

Whoa! We have come to the end of this tutorial. I only added the functions to Create and get an Employee and Department. You are free to explore more and add more functions. 

Awesome! Please share it with anyone you think could use this information. Thanks for reading. As always, if you have any questions, comments, or concerns about this post, feel free to leave a comment below.

##Reference

{% youtube Yy9wOhiWBJg %}