Improve GraphQL Performance with Large Responses
Posted by Oscar Pérez
GraphQL is a great query language for APIs which lets TravelgateX communicate its business model to all partners effectively.
Some GraphQL features used at TravelgateX:
- Product’s API standardization on naming, errors, warnings, etc…
- Fully generated documentation in a single endpoint api.travelgatex.com
- Improve developer experience, especially for UI developments
- Standardized runtime validation data
- Easily API versioning knowing what fields are actually being used by customers
However, some GraphQL features have consequences on performance because most of the intensive workloads are executed in GraphQL backends. We have detected this performance degradation in scenarios returning responses with +10000 nodes and/or +1Mb size.
Specifically, backend services performance degradation is related to CPU usage to support GraphQL features as:
These features facilitate Front-Back GraphQL development for frameworks like React or Angular. However, in the case of a Back-Back GraphQL implementation, developers don’t use a specific GraphQL client, they generally use well-known common HTTP client libraries.
So, the challenge is how to offer the best of two worlds:
- For large responses, high-performance Back-Back communication similar to protocols like REST or gRPC
- For the rest of 99% use cases, great DX and server-side workload using GraphQL features
And these are the good news: it’s all about JSON!
TravelgateX backend servers will be notified by the client application and will return a valid JSON response conforming GraphQL schema, which will not support all of the restrictions defined in the GraphQL specification.
- To implement 100% GraphQL specification on the request message and continue tracking usage on requested fields
- To return expected JSON responses for applications not using GraphQL features, such as field aliases or ordination
- To minimize development efforts for clients with current API GraphQL implementation
Since TravelgateX GraphQL implementation already uses JSON in the response as recommended in GraphQL Best Practices, the solution is to return responses that do not use GraphQL specific features. The client’s JSON parser should expect:
- To receive more fields than requested (in some cases)
- To receive fields in a different order than requested (likely)
- To never receive aliases
To activate this mode, the client application must add the HTTP header TGX-Content-Type:graphqlx/json in the request:
curl -X POST -H "Content-Type:application/json" -H "TGX-Content-Type:graphqlx/json" -H "Authorization: Apikey [MY_API_KEY]" --data @data_file.txt --compressed https://api.travelgatex.com
When expecting to receive +10000 nodes in a non-paginated query, backend developers should use the header specified above.
This will only happen in the scenarios described below:
- hotelX.search queries requesting +500 hotels: With an average of 20 options per hotel
- hotelX.search queries requesting 1..n hotels and using a sparse field key in the aggregation plugin
If you are unsure about previous scenarios use the header in all hotelX.search queries.
To implement this feature, please follow these steps:
- Check that your JSON parser is updated to the last schema as the Array Fields previously defined as single Scalars can produce unexpected JSON marshalling
- Add the HTTP header to your request(s)
- Test a sample call for every request using the header
- Enjoy the performance 🙂
The GraphQL community is focusing on improving the performance issues flagged by different users, but for us time to market is critical, so we are getting ahead of the game and putting in place our own solutions to handle large responses using GraphQL.
The performance degradation has been detected and fixed. TravelgateX will continue to strive to offer the best performance possible, offering alternative connectivity protocols for our clients. We’ll use Google Cloud API development approach, advising our clients of the best protocol for each use case.Learn More About TravelgateX