Reader small image

You're reading from  Web API Development with ASP.NET Core 8

Product typeBook
Published inApr 2024
PublisherPackt
ISBN-139781804610954
Edition1st Edition
Concepts
Right arrow
Author (1)
Xiaodi Yan
Xiaodi Yan
author image
Xiaodi Yan

Xiaodi Yan is a seasoned software engineer with a proven track record in the IT industry. Since 2015, he has been awarded Microsoft MVP, showcasing his dedication to and expertise in .NET, AI, DevOps, and cloud computing. He is also a Microsoft Certified Trainer (MCT), Azure Solutions Architect Expert, and LinkedIn Learning instructor. Xiaodi often presents at conferences and user groups, leveraging his extensive experience to engage and inspire audiences. Based in Wellington, New Zealand, he spearheads the Wellington .NET User Group, fostering a vibrant community of like-minded professionals. Connect with Xiaodi on LinkedIn to stay updated on his latest insights.
Read more about Xiaodi Yan

Right arrow

Getting Started with GraphQL

In Chapter 11, we explored how to create a gRPC service in ASP.NET Core. gRPC is a high-performance RPC framework that facilitates communication between services. We discussed the field types used in protobuf messages, and how to define four types of gRPC services: unary, server streaming, client streaming, and bidirectional streaming. Additionally, we learned how to configure gRPC services in ASP.NET Core and how to call gRPC services from a client application.

Next, we will explore another shape of web APIs: GraphQL. GraphQL is a query-based API that allows clients to specify the data they need, which solves the problem of over-fetching and under-fetching data. Besides, GraphQL supports mutations, which allow clients to modify data. In this chapter, we will learn about some basic concepts of GraphQL and how to create a GraphQL API in ASP.NET Core. We will cover the following topics in this chapter:

  • Recap of GraphQL
  • Setting up a GraphQL...

Technical requirements

The code examples in this chapter can be found at https://github.com/PacktPublishing/Web-API-Development-with-ASP.NET-Core-8/tree/main/samples/chapter12. You can use VS 2022 or VS Code to open the solutions.

Recap of GraphQL

GraphQL offers a flexible way to query and mutate data. The main difference between GraphQL and REST is that GraphQL allows clients to specify the data they need, whereas REST APIs return a fixed set of data. GraphQL treats data as a graph, and it uses a query language to define the shape of the data. This addresses the issues of over-fetching and under-fetching data by enabling clients to specify their data requirements. Additionally, it supports mutations, empowering clients to modify data as needed.

While REST APIs have multiple endpoints for different resources, GraphQL is typically served over a single endpoint, usually /graphql, which exposes a schema that describes the data. All queries and mutations are sent to this endpoint. The schema is defined using a GraphQL Schema Definition Language, which is the contract between the client and the server. The schema defines the types of data and the operations that can be performed on the data. The client can use...

Setting up a GraphQL API using HotChocolate

To begin with, you can download the code example named SchoolManagement for this chapter from the chapter12\start folder. This sample project has some basic code for an AppDbContext class and a Teacher class, as well as some seed data. The Teacher class has the following properties:

public class Teacher{
    public Guid Id { get; set; }
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string? Phone { get; set; }
    public string? Bio { get; set; }
}

You can open the project in VS Code or VS 2022. We will integrate HotChocolate into the project to create a GraphQL API following these steps:

  1. Add the HotChocolate.AspNetCore NuGet package to the project. This package contains the ASP...

Adding mutations

In the previous section, we learned how to create a GraphQL API using HotChocolate. We added a query root type to query data. In this section, we will discuss how to modify data using mutations.

Mutations are used to modify data in GraphQL. A mutation consists of three parts:

  • Input: The input is the data that will be used to modify the data. It is named with the Input suffix following the convention, such as AddTeacherInput.
  • Payload: The payload is the data that will be returned after the mutation is executed. It is named with the Payload suffix following the convention, such as AddTeacherPayload.
  • Mutation: The mutation is the operation that will be executed. It is named as verb + noun following the convention, such as AddTeacherAsync.

Let us add a mutation to create a new teacher. We will use the following steps:

  1. Create an AddTeacherInput class in the GraphQL/Mutations folder, as shown here:
    public record AddTeacherInput(  ...

Using variables in queries

In the previous section, we learned how to query data and modify data using GraphQL queries and mutations. In this section, we will discuss how to use variables in queries.

GraphQL allows you to use variables in queries. This is useful when you want to pass parameters to the query. We can create a query that accepts an id parameter and returns the teacher with the specified ID. Follow these steps to create the query:

  1. Add a GetTeacher() method in the Query class, as follows:
    public async Task<Teacher?> GetTeacher(Guid id, [Service] AppDbContext context) =>    await context.Teachers.FindAsync(id);

    The preceding code adds a GetTeacher() method to the Query class. It takes an id parameter and returns the teacher with the specified ID.

  2. Now, you can use the $ sign to define a variable in the query. For example, you can use the following query to get a teacher by ID:
    query getTeacher($id: UUID!) {  teacher(id: $id...

Defining a GraphQL schema

Usually, a system has multiple types of data. For example, a school management system has teachers, students, departments, and courses. A department has multiple courses, and a course has multiple students. A teacher can teach multiple courses, and a course can be taught by multiple teachers as well. In this section, we will discuss how to define a GraphQL schema with multiple types of data.

Scalar types

Scalar types are the primitive types in GraphQL. The following table lists the scalar types in GraphQL:

Using data loaders

In the previous section, we learned how to integrate HotChocolate with EF Core. We also learned how to use the DbContextPool feature to fetch data in multiple resolvers. However, we found that there are many database queries for each Department object in the Teacher list. That is because the resolvers for each Department object are executed separately, querying the database by each DepartmentId property in the list. This is similar to the N+1 problem we discussed in Chapter 1. The difference is that the N+1 problem occurs on the client side in REST APIs, while it occurs on the server side in GraphQL. To solve this problem, we need to find a way to load the batch data efficiently.

HotChocolate provides a DataLoader mechanism to solve the N+1 problem. The data loader fetches data in batches from the data source. Then, the resolver can retrieve the data from the data loader, rather than querying the data source directly. The data loader will cache the data for the...

Dependency injection

In the previous code examples, we use IDbContextFactory<AppDbContext> and AppDbContext directly in the resolvers. In order to encapsulate our data access logic, we can add a service layer to implement our business logic. HotChocolate supports dependency injection for resolvers. In this section, we will learn how to inject other services into the resolvers.

To demonstrate how to use dependency injection in HotChocolate, we will add an interface named ITeacherService and a class named TeacherService, as follows:

public interface ITeacherService{
    Task<Department> GetDepartmentAsync(Guid departmentId);
    Task<List<Teacher>> GetTeachersAsync();
    Task<Teacher> GetTeacherAsync(Guid teacherId);
    // Omitted for brevity
}
public class TeacherService(IDbContextFactory<AppDbContext> contextFactory) : ITeacherService
{
    ...

Interface and union types

HotChocolate supports the use of interfaces and union types in GraphQL. In this section, we will explore how to incorporate these features into your GraphQL schema. Interfaces provide a way to group types that share common fields, while union types allow for the creation of a single type that can return different object types. With HotChocolate, you can easily implement these features to enhance the functionality of your GraphQL schema.

Interfaces

To prepare the examples of GraphQL interfaces, we have an ISchoolRoom interface and two classes that implement the interface, as follows:

public interface ISchoolRoom{
    Guid Id { get; set; }
    string Name { get; set; }
    string? Description { get; set; }
    public int Capacity { get; set; }
}
public class LabRoom : ISchoolRoom
{
    public Guid Id { get; set; }
    public string...

Filtering, sorting, and pagination

In this section, we will learn how to implement filtering, sorting, and pagination in HotChocolate. These features are very important for a real-world application. We will use the Student object as an example to demonstrate how to implement these features. The Student class is defined as follows:

public class Student{
    public Guid Id { get; set; }
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string? Phone { get; set; }
    public string Grade { get; set; } = string.Empty;
    public DateOnly? DateOfBirth { get; set; }
    public Guid GroupId { get; set; }
    public Group Group { get; set; } = default!;
    public...

Visualizing the GraphQL schema

When the GraphQL API becomes more complex, it is difficult to understand the schema. We can use GraphQL Voyager to visualize the GraphQL schema. GraphQL Voyager is an open-source project that can visualize the GraphQL schema in an interactive graph. It is a frontend application that can be integrated with the GraphQL API. To use it in our ASP.NET Core application, we can use the GraphQL.Server.Ui.Voyager package. This package is part of the GraphQL.NET project.

Follow these steps to use GraphQL Voyager in our application:

  1. Install the GraphQL.Server.Ui.Voyager package using the following command:
    dotnet add package GraphQL.Server.Ui.Voyager
  2. Add the following code to the Program.cs file:
    app.MapGraphQLVoyager();

    The preceding code adds a middleware that maps the Voyager UI to the default URL ui/voyager. If you want to specify a different URL, you can pass the URL as a parameter, as in this example:

    app.MapGraphQLVoyager("/voyager");
  3. ...

Summary

In this chapter, we explored how to use HotChocolate and Entity Framework Core to create a GraphQL API. We discussed how to define object types, queries, and mutations, as well as how to use dependency injection to inject the DbContext instance and services into the resolver. We also introduced the data loader, which can reduce the number of queries to the database. Additionally, we discussed interface and union types, which are useful for defining polymorphic types. Finally, we explored how to use filtering, sorting, and pagination in HotChocolate.

In the next chapter, we will discuss SignalR, which is a real-time communication library in ASP.NET Core.

Further reading

It is important to note that GraphQL is a comprehensive query language and there are many features that we were unable to cover in this chapter. For example, GraphQL supports subscriptions, which enable real-time communication with the GraphQL API. To learn more about HotChocolate and GraphQL, please refer to the following resources:

In a microservice architecture, we can use Apollo Federation to create a GraphQL gateway. Apollo Federation can combine multiple GraphQL APIs into a single GraphQL API. We will not cover Apollo Federation here as it is out of the scope of this book. To learn more about Apollo Federation, please refer to the following resources:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Web API Development with ASP.NET Core 8
Published in: Apr 2024Publisher: PacktISBN-13: 9781804610954
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Xiaodi Yan

Xiaodi Yan is a seasoned software engineer with a proven track record in the IT industry. Since 2015, he has been awarded Microsoft MVP, showcasing his dedication to and expertise in .NET, AI, DevOps, and cloud computing. He is also a Microsoft Certified Trainer (MCT), Azure Solutions Architect Expert, and LinkedIn Learning instructor. Xiaodi often presents at conferences and user groups, leveraging his extensive experience to engage and inspire audiences. Based in Wellington, New Zealand, he spearheads the Wellington .NET User Group, fostering a vibrant community of like-minded professionals. Connect with Xiaodi on LinkedIn to stay updated on his latest insights.
Read more about Xiaodi Yan

Scalar type

Description

.NET type

Int

Signed 32-bit integer

int

Float

Signed double-precision floating-point value specified in IEEE 754

float or double

String

...