Creating API Development in ASP.NET Using GraphQL?

Introduction

In this article, we are going to discuss the API Development in .NET with GraphQL. What is GraphQL? How to set up GraphQL in .NET application.

Why GraphQL?

APIs allow software to speak to each other. Currently, the dominant design model is REST. Though it is known to build long-lasting APIs, it has issues that come with today’s applications, especially with the rise of mobile app consumers. Queries done with REST require many HTTP endpoints that return fixed data structures which can easily result in excess data. Issues come also with frequent updates to the applications since knowing what individual clients need is very difficult.



What is GraphQL?

GraphQL was built by Facebook in 2012 (publicly released and open sourced in 2015) for their mobile and web apps. It was designed precisely for the need for more flexibility and efficiency in the client, server communication.


GraphQL has one “smart” endpoint that can take complex operations and return only the data the client needs. It is an open-sourced framework for the development and deployment of server less GraphQL back ends. GraphQL is a data query language for APIs and runtime for fulfilling those queries with your existing data (GraphQL.org).


GraphQL

GraphQL was created to solve the issues of the times APIs, especially with over fetching. This was caused by the basic structure of the queries, causing a series of requests with excess data. This is especially an issue with mobile apps that are used with devices and network conditions that can´t handle huge 9 amounts of data and payloads. Today it is maintained by a vast community across the globe consisting of both companies and individuals (Howtographql.com).


GraphQL Query:


{ hero{ name } }

Result(JSON format):


{ “data”:{ “hero”:{ “name”: “Jeetendra” } } }

Let's start with step by step implementation in ASP .NET Core 2.0.


Now, what next your Web API project is created now time to setup the GraphQL in that API project using following steps:



Next, set up the models for our API, create a new folder called “Models” and add “Book” and “Author” models into that.


public class Book { public int Id { get; set; } public string Name { get; set; } public Author Author { get; set; } }
public class Author { public int Id { get; set; } public string Name { get; set; } public List<Book> Books { get; set; } }

And now, we need to create a “Data” folder, and add “IBookRepository” and “IAuthorRepository” interfaces into that.


public interface IBookRepository { Task<List<Book>> GetBookssAsync(); Task<List<Book>> GetBooksWithByCategoryIdAsync(int categoryId); Task<Book> GetBookAsync(int id); }
public interface IAuthorRepository { Task<List<Author>> CategoriesAsync(); Task<Author> GetCategoryAsync(int id); }

Let’s implement “IBookRepository” and “IAuthorRepository” interfaces with a few sample data like as below.


public class AuthorRepository : IAuthorRepository { private List<Author> _authors; public AuthorRepository() { _authors = new List<Author>{ new Author() { Id = 1, Name = "Jeetendra G" }, new Author() { Id = 2, Name = "Anjali G" } }; } public Task<List<Author>> AuthorsAsync() { return Task.FromResult(_authors); } public Task<Author> GetAuthorAsync(int id) { return Task.FromResult(_authors.FirstOrDefault(x => x.Id == id)); } } public class BookRepository : IBookRepository { private List<Book> _books; public BookRepository() { _books = new List<Book>{ new Book() { Id = 1, AuthorId = 1, Name = "AngularJS" }, new Book() { Id = 2, AuthorId = 1, Name = "ReactJS" }, new Book() { Id = 3, AuthorId = 1, Name = "GraphQL" } }; } public Task<Book> GetBookAsync(int id) { return Task.FromResult(_books.FirstOrDefault(x => x.Id == id)); } public Task<List<Book>> GetBooksAsync() { return Task.FromResult(_books); } public Task<List<Book>> GetBooksWithByCategoryIdAsync(int authorId) { return Task.FromResult(_books.Where(x => x.AuthorId == authorId).ToList()); } }

Object Types

The most basic components of a GraphQL schema are object types, which just represent a kind of object you can fetch from your service, and what fields it has.




Now we will create two ObjectGraphType into the “Models” folder, and these are “BookType” and “AuthorType” classes.


public class BookType : ObjectGraphType<Book> { public BookType(IAuthorRepository authorRepository) { Field(x => x.Id).Description("Book id."); Field(x => x.Name).Description("Book name."); Field<AuthorType>( "author", resolve: context => authorRepository.GetAuthorAsync(context.Source.AuthorId).Result ); } }
public class AuthorType : ObjectGraphType<Author> { public AuthorType(IBookRepository bookRepository) { Field(x => x.Id).Description("Author id."); Field(x => x.Name, nullable: true).Description("Author name."); Field<ListGraphType<BookType>>( "books", resolve: context => bookRepository.GetBooksByAuthorIdAsync(context.Source.Id).Result.ToList() ); } }

Let’s create a root type to use the query operations. For that, create a new class called “LibraryQuery“.


public class LibraryQuery : ObjectGraphType { public LibraryQuery(IBookRepository bookRepository, IAuthorRepository authorRepository) { Field<BookType>( "book", arguments: new QueryArguments( new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "id", Description = "Book id" } ), resolve: context => bookRepository.GetBookAsync(context.GetArgument<int>("id")).Result ); Field<AuthorType>( "author", arguments: new QueryArguments( new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "id", Description = "Author id" } ), resolve: context => authorRepository.GetAuthorAsync(context.GetArgument<int>("id")).Result ); } }

Next, can create the schema which will describe the structure of the data.


public class LibrarySchema : Schema { public LibrarySchema(Func<Type, GraphType> resolveType) : base(resolveType) { Query = (LibraryQuery)resolveType(typeof(LibraryQuery)); } }

The Query and Mutation types

There are two types that are special within a schema:

schema { query: Query mutation: Mutation }

First one is to prepare GraphQLendpoint, another one is to perform service injection operations. So, let’s create a request class called “GraphQLRequest” into the “Models” folder as below.


public class GraphQLRequest { public string OperationName { get; set; } public string NamedQuery { get; set; } public string Query { get; set; } public string Variables { get; set; } }

After creating the request object, we can prepare the controller. Therefore, create a “GraphQLController” class as following below.


[Produces("application/json")] [Route("api/GraphQL")] public class GraphQLController : Controller { private readonly IDocumentExecuter _documentExecuter; private readonly ISchema _schema; public GraphQLController(IDocumentExecuter documentExecuter, ISchema schema) { _documentExecuter = documentExecuter; _schema = schema; } [HttpPost] public async Task<IActionResult> Post([FromBody]GraphQLRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var executionOptions = new ExecutionOptions { Schema = _schema, Query = request.Query }; try { var result = await _documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false); if (result.Errors?.Count > 0) { return BadRequest(result); } return Ok(result); } catch (Exception ex) { return BadRequest(ex); } } } }

Now, the last thing is the dependency injection. Let’s inject the services in the “Startup” class as follows.


// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddScoped<LibraryQuery>(); services.AddTransient<IBookRepository, BookRepository>(); services.AddTransient<IAuthorRepository, AuthorRepository>(); services.AddScoped<IDocumentExecuter, DocumentExecuter>(); services.AddTransient<BookType>(); services.AddTransient<AuthorType>(); var sp = services.BuildServiceProvider(); services.AddScoped<ISchema>(_ => new LibrarySchema(type => (GraphType)sp.GetService(type)) { Query = sp.GetService<LibraryQuery>() }); }

Finally, we created the setup the API application development with GraphQL. Last steps to test this created API using the Postman or you can use Swagger as well to test.


If you don’t have the Postman chrome extension, you can install this chrome extension using following link:
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en


Following are the steps to test the API application:


Summary:

I hope that beginners, developers, understood the concept of GraphQL, What is GraphQL? API Development in .NET with GraphQL. If you have any suggestion regarding this article, then please contact me.


“Learn It, Share it.”


  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img
  • img