# GraphQL with Azure Functions

Despite being a industry standard for Web API's and the numerous advantages that REST offers, it suffers from a few shortcomings. For instance, REST requires multiple endpoints defined for multiple requests which leads to an increased overhead and resource wastages. [GraphQL](https://graphql.org) alleviates this issue by returning what's asked for through a single call.

Say for example if you want to get details from a product schema, you will have to ask for specifics like Productid, Product Name and GraphQL will return exactly what it has been asked. The data is returned in JSON format. In short, GraphQL can be defined as a query language for API's that can be modelled according to the information required. It allows to request related data in a single called by avoiding the need for roundtrips to the server.

### Components of GraphQL

GraphQL components are the major building blocks of GraphQL query language. They include :

* **Types:** Defines the type of an object that GraphQL returns.
    
* **Queries:** The most fundamental block of GraphQL. It enables requests to fetch only the desired data from the source in a single call.
    
* **Schema** : It defines the structure of the GraphQL API. It basically acts as an intermediary between the client and server that species what queries can be made and how mutations can manipulate data.
    
* **Mutations :** They are operations that allow data manipulations like inserts, deletes and updates.
    
* **Subscriptions**: Enables real time capabilities that allows clients to subscribe to events on server and receive real time updates/changes
    

Note : Mutations and Subscriptions are completely optional.

### Implementation

GraphQL can be implemented in various programming languages. For `.Net` there are two implementations :

* [**GraphQL for .NET**](https://graphql-dotnet.github.io/docs/getting-started/introduction/)
    
* [**Hot Chocolate**](https://chillicream.com/docs/hotchocolate/v13)
    

both of which are open source projects.

We would use HotChocolate. To get started use `Azure Functions isolated process` mode and install the following Nuget package: `HotChocolate.AzureFunctions.IsolatedProcess`.

We then define our model and in the model we define three properties `ProductName`,`ProductId`,`ProductCategory` that we want to expose through our schema.

```csharp
    public class Product
    {
        public string ProductName { get; set; }
        public int ProductId { get; set; }
        public ProductCategory CategoryName { get; set; }
    }

    public class ProductCategory
    {
        public string CategoryName { get; set; }
    }
```

In Hotchocolate , properties defined with a public accessor act as resolver that returns the underlying values.

Next, create a supporting class `ProductClass` that defines the data and returns it.

```csharp
public class ProductClass
{

    public List<Product> GetProducts()
    {
        var products = new List<Product>
{
    new Product
    {
        ProductId = 1,
        ProductName = "Furniture",
        CategoryName = new ProductCategory
        {
            CategoryName = "Home Essentials"
        }
    },
    new Product
    {
        ProductId = 2,
        ProductName = "Electronics",
        CategoryName = new ProductCategory
        {
            CategoryName = "Gadgets"
        }
    },
    new Product
    {
        ProductId = 3,
        ProductName = "Books",
        CategoryName = new ProductCategory
        {
            CategoryName = "Education"
        }
    }
};
        return products;
    }

    public Product GetProduct(int ProductId) { return GetProducts().FirstOrDefault(p => p.ProductId == ProductId); }
    public List<Product> GetAllProducts() { return GetProducts(); }

};
```

Next implement a `Query`:

The query has two methods - `GetProduct` and `GetAllProducts`. `GetProduct` fetches a given `product` and `GetAllProducts` retrieves all `products` . The `GetProduct()` method accepts an argument `ProductId` which is resolved by GraphQL queries.

```csharp
public Product GetProduct(int productid, [Service] ProductClass product) { return product.GetProduct(productid); }
public List<Product> GetAllProducts([Service] ProductClass product) { return product.GetAllProducts(); }
```

Advantage with `Azure Functions isolated process` is that we have `Program.cs` through which we can control the startup. We register our `Query`in `Program.cs`.The class looks like this

```csharp
using GraphQL;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .AddGraphQLFunction(a => a.AddQueryType<Query>())
    .ConfigureServices(b => b.AddSingleton<ProductClass>())
    .Build();

host.Run();
```

The `Function` class defines an Azure function `GraphQLHttpFunction` that serves as a GraphQL endpoint that handles HTTP requests to execute GraphQL queries and mutations. The function can handle both `GET` and `POST` HTTP methods. The field \_`execution`\_ references an object that implements `IGraphQLRequestExecutor` interface. The route pattern defines that the function will respond to requests made to `graphql/{**path}` endpoint where `path` can be any subpath after `graphql`.

```csharp
  public class GraphQLFunction
  {
      private readonly IGraphQLRequestExecutor _execution_;

      public GraphQLFunction(IGraphQLRequestExecutor executor)
      {
          _execution_ = executor;

      }

      [Function("GraphQLHttpFunction")]
      public Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "graphql/{**path}")] HttpRequestData request)
          => _execution_.ExecuteAsync(request);
  }
```

### Execution

We are all set to run the application. Build the application and copy the function `URI` and paste it in the browser

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724970141728/4d7cdb3d-9c69-44b2-9b01-15e990aa7433.png align="center")

The `URI` would land you on the [Banana Cake Pop IDE](https://chillicream.com/products/bananacakepop/). The IDE can be used for testing the GraphQL queries.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1724971488581/0e65dbc2-389a-4dd1-a68a-474817144280.gif align="center")

Another option to test the GraphQL API is through `Curl` or JavaScript code with `fetch`. Here is a sample Python call to the GraphQL API that we created.

```python
import requests

url = "http://localhost:7146/api/graphql"
headers = {"Content-Type": "application/json"}
query = """
query Products {
  product(productid: 1) {
    productId
    productName
    categoryName {
      categoryName
    }
  }
}
"""

response = requests.post(url, json={"query": query}, headers=headers)

print(response.json())
```

That's all folks..

In the [next](https://www.azureguru.net/filters-paging-sorting-and-mutations-with-graphql-in-aspnet#heading-mutations) article we look into how Mutations and Subscription work in GraphQL.

### Closing Notes

Integrating GraphQL with Azure Functions provides a powerful and scalable solution for building modern APIs on a serverless architecture. By leveraging the flexibility of GraphQL and the serverless capabilities of Azure Functions along with the upper hand GraphQL has over REST, robust and highly scalable applications can be built.

Thanks for reading !!!
