Azure APIM and GraphQL
Author:
Daniel Fang
Published: July 24, 2023
5 minutes to read
Azure API Management supports GraphQL APIs (graphql.org, an open-source, industry-standard query language for APIs). GraphQL operates over a single endpoint using HTTPs and provides declarative, efficient data fetching. Leveraging APIM’s security, governance & throttling capabilities, we can develop GraphQL on Azure with confidence.
In this post, we will have a quick overview of using APIM for GraphQL. There are two models in APIM that we can use for GraphQL API.
- APIM Pass-through GraphQL
- APIM Synthetic GraphQL
APIM Pass-through GraphQL
APIM Pass-through GraphQL connects APIM to an existing GraphQL service endpoint. It supports GraphQL queries, mutations, and subscriptions. Popular GraphQL service could be hosted on Function App or App Service to utilise Azure scaling options. To know more on how to do that check the section [Host GraphQL on Function App] below.
To import existing API, use the APIM wizard and select GraphQL option.
You can use the following two options to define schema:
- GraphQL schema can be retrieved directly from existing service
- Or upload schema from local file
The API creation wizard is similar to normal Restful API creation. Once created, you can utlize APIM’s capability via APIM policies.
APIM Synthetic GraphQL
The second model is APIM Synthetic GraphQL, it can combine multiple API endpoints, even access to Azure resources like Azure SQL or Cosmos DB. It has the following key features:
- API based on a custom GraphQL schema
- Support for GraphQL queries, mutations, and subscriptions
- Configure custom resolvers (support HTTP API, Azure SQL & Cosmos DB)
- Develop GraphQL schemas while consuming data from legacy APIs
Here is an example of Synthetic GraphQL on APIM in below diagram.
- Client app sends a single HTTP POST (containing a GraphQL query) to APIM
-
APIM’s GraphQL resolver fetches 4 individual JSON responses by calling:
2a. GraphQL API hosted in function app
2b. Restful API hosted in logic app
2c. Azure SQL database
2d. CosmosDB - APIM combines JSON and generates final response to client.
Host GraphQL on Function App
Apollo GraphQL is a well-known open-source, spec-compliant GraphQL server. You can host its node.js implementation in Function App or App Service. If you are a .NET & C# deveroper, Hot Chocolate is a feature-rich, open-source GraphQL server in the .NET ecosystem.
Here is an example Apollo GraphQL (Node.js) app that can be hosted on Function App: js-e2e-azure-function-graphql-hello
Below are a few tips when running the example on Function App. Please follow the comments inside the setting snippets below.
- Inside graphql/function.json:
- bindings->authLevel
- bindings->name
- scriptFile
{
"bindings": [
{
// use anonymous only for testing
// double check this value if getting 401 error on Function App,
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post",
"options"
]
},
{
"type": "http",
"direction": "out",
// Function App exposes GraphQL response
"name": "$return"
}
],
// point to GraphQL file location
"scriptFile": "../dist/graphql/index.js"
}
- Inside graphql/index.ts:
- import library
- CORS settings.
// use Apollo's Function App lib
import { ApolloServer, gql} from "apollo-server-azure-functions";
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => "Hello from our GraphQL backend!",
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
debug: true
});
export default server.createHandler({
cors: {
// allow CORS for Function App url
// required if you use remote Apollo studio for testing, otherwise you will get CORS error
origin: ['*', "https://studio.apollographql.com"],
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: ["access-control-allow-credentials", "access-control-allow-origin", "content-type"]
},
});
- Inside tsconfig.json
- esModuleInterop value
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"rootDir": ".",
"sourceMap": true,
"strict": false,
// turn on esModuleInterop
"esModuleInterop": true
}
}
- Inside host.json
- routePrefix value
{
"version": "2.0",
"extensions": {
"http": {
// remove extra api from url. routePrefix is /api/ in below example
// https://api.mydomain.com/api/graphql
"routePrefix": ""
}
}
}
Summary
GraphQL provides an efficient way to fetch data. When you make a request, GraphQL queries the server and returns a response specific to your query. Comparing to REST API, it addresses the issue of over-fetching or under-fetching of data. Azure can suport GraphQL in both API Management and serverless app.
I hope the post give you some new idea to utilise GraphQL in APIM.