REST APIs have been with us for over 20 years now. In that time, our expectations of client applications have grown. We expect client applications to run on mobile devices with low bandwidth, yet still be responsive. Unfortunately, REST APIs restrict us in three basic ways:
- It takes too many requests to fulfill the data needs for a single page.
- The REST API returns too much data for the page being rendered.
- The client application needs to poll to get new information.
There have been various attempts to solve these issues, and the current favorite is GraphQL. GraphQL is a protocol specification that explicitly solves these issues. The client application can specify the data they need to render a page in a query document that is sent as a single request to the GraphQL service. A client application can also subscribe to changes in the data through a real-time WebSocket connection, allowing notifications to happen in a timely manner.
Protect your GraphQL API
As is normal with a new protocol, GraphQL comes with its own set of challenges. One of the key benefits of GraphQL is introspection. A developer can query the GraphQL service to find out information on the models available and the supported operations. While this is a good thing for developer velocity, it provides an attack vector when used in production. Similarly, the GraphQL service can allow a developer to ask for any data they want, which can result in very complex queries. Eventually, that data is served by some sort of database. Administrators want to control the query complexity to ensure that the database offers a good response to everyone.
We have recently announced that GraphQL APIs are generally available in Azure API Management. You can add a GraphQL API to your Azure API Management instance and protect it just like all the other APIs that you have. This means you can add subscription keys, rate limiting, operational monitoring, and early rejection for authorization at the gateway level so that your backend service is always handling legitimate calls.
The latest release of Azure API Management adds several GraphQL specific controls, including query depth and query size analysis, schema checking, and authorization rules – allowing you to turn off introspection at the gateway level, but leave it on for your developers. You don’t even need to upload the same schema to the gateway as you have on your backend service. You can remove models and operations from the schema that aren’t relevant to outside parties, while still supporting them on the inside of your backend network. In addition, we added support for exposing GraphQL APIs via the Developer Portal. This allows you to advertise GraphQL APIs to your developer community with standard documentation and a query console for developer testing.
Augment your GraphQL API
There are times that you want to augment your GraphQL API. Maybe you have a User model and want to add the current title and location of the user from Azure Active Directory, or your database has a customer ID, but lacks the customer details. With this release, we are also adding a preview feature: GraphQL resolvers in Azure API Management. Resolvers are a key concept in GraphQL, and providing them in Azure API Management allows us to produce a synthetic GraphQL service. You can retrieve additional information by attaching a HTTP-based GraphQL resolver to a field of your GraphQL schema. For instance, you can attach a resolver to the title field of your User type.
When the GraphQL request comes into the API Management GraphQL API, the query is parsed, and the request for the title is recognized. Since we have a resolver for that field, it is removed from the query before being passed on to your backend service. Once the response comes back from the backend service, we run the resolver for each object that needs it. In our hypothetical case, we would do a HTTP request to the Microsoft Graph service to obtain the user record, then extract the title from that before combining the data with the existing response.
Build your GraphQL API
But why stop there? With the preview GraphQL resolvers, you can remove the GraphQL backend completely and define a complete set of resolvers to fulfill any query. The resolvers can easily be written in Azure Functions or take advantage of REST APIs across M365, Azure, your own services, or third party services such as Shopify, Marketo, or ServiceNow. The Synthetic GraphQL service will run all the required requests and combine the results into the response to the user.
Support for GraphQL APIs is rolling out to all public Azure regions. Support for WebSocket based subscriptions is available only on dedicated SKUs, and not available on Consumption. Synthetic GraphQL APIs are similarly restricted to dedicated SKUs (Developer, Basic, Standard, and Premium).