GraphQL with Azure Functions

Sachin Nandanwar
4 min readAug 30, 2024

--

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 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 :

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.

    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.

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.

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

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

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.

  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.

The URI would land you on the Banana Cake Pop IDE. The IDE can be used for testing the GraphQL queries.

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.

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 another next 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 !!!

Originally published at : https://www.azureguru.net/graphql-with-azure-functions

--

--