REST and GraphQL API Principles
Once upon a time a software was basically a self contained executable that ran on your machine. It rarely reached out something outside of the computer on which it ran. This was the era of Visual Basic and MS access.
Over time with rise of networks and internet software started executing remote code. Basically a client application would request some processing on a remote machine and get result back. This was done using a complex and very enterprise like system called SOAP. It used XML and was extremely complex. These were called SOA (Service Oriented Architecture).
People rightly saw that SOAP was bloated, needlessly complex and not very human friendly. So REST was seen as a better alternative with JSON replacing XML.
In this article we are not going to explain what REST is. You can find plenty of online content around it. But the principle of rest was very simple. It used existing HTTP protocol primitives to mimic a remote call while also setting up a conventions as to what method (GET vs POST Vs PUT etc.) is to be called.
REST views itself as a mechanism to either read or mutate remote data entities. This is different from SOAP because SOAP is primarily a remote procedure call (RPC) mechanism.
While they are pretty much interchangeable there is this fundamental semantic difference between both.
As REST became more popular it was clear that for complex web apps, it is mostly GET that gets called more often than actual mutations. For example, for Facebook feed you rarely create content but you are mostly accessing the feed. So most of the times GET calls to read data dominate everything else.
Soon, reading becomes more complex. For example, you need to display User’s email and last login time on some page. You end up doing multiple calls where in one call you GET /user/1 to get all user’s details and another GET /user/login_history/1 to get the user’s login history.
Not only this means multiple calls but it also means fetching lots of data we do not need at the client.
GraphQL
GraphQL still uses REST underneath but provides additional standards to specify what data you need and fetches only that data. In that sense GraphQL can be seen as SQL over REST.
Here is what GraphQL provides.
Efficient data fetching : Only data that is needed is fetches
Reduction in number of calls : Since clients fetch limited data and possibly with joins this reduces actual HTTP calls.
Strong Typing : The data types are strongly typed.
Hierarchical Structure: GraphQL's hierarchical structure naturally represents relationships between objects, making it well-suited for complex data models.
Example GraphQL queries:
query {
posts(publishedAfter: "2023-01-01") {
title
author {
name
}
}
}
query {
user(id: 123) {
name
posts(limit: 5, sort: { field: "createdAt", order: DESC }) {
title
comments(limit: 2) {
text
author {
name
}
}
}
}
}
API Principles to keep in mind when designing for GraphQL
1. Clear and Concise Schema Design:
Meaningful Naming: Use descriptive and consistent names for types, fields, and arguments.
Well-Defined Types: Utilize GraphQL's type system effectively to model your data and relationships accurately.
Documentation: Provide clear and comprehensive documentation for your schema, explaining the purpose of each type and field.
2. Efficient Data Fetching:
Optimize Queries: Encourage clients to request only the data they need to avoid over-fetching.
Nullability: Clearly define which fields are nullable to help clients handle potential missing data.
Pagination: Implement pagination for large datasets to improve performance and reduce payload sizes.
3. Error Handling:
Informative Errors: Provide detailed and helpful error messages to guide clients in resolving issues.
Consistent Error Format: Use a consistent format for error responses to facilitate client-side error handling.
4. Security:
Authentication and Authorization: Implement appropriate security measures to protect your API from unauthorized access.
Input Validation: Validate client input to prevent malicious or invalid data from affecting your system.
Rate Limiting: Consider implementing rate limiting to prevent abuse and protect your server resources.
5. Versioning and Evolution:
Schema Evolution: Plan for schema changes and use deprecation to avoid breaking existing clients.
Versioning: If necessary, implement versioning strategies to manage breaking changes.
6. Performance Optimization:
Caching: Utilize caching mechanisms to improve response times and reduce server load.
DataLoader: Leverage DataLoader to batch and cache data fetching operations.
Connection Model: Consider using the Relay Connection model for efficient pagination and connections between objects.
7. Community and Tooling:
Follow Conventions: Adhere to common GraphQL conventions and best practices.
Utilize Tools: Leverage existing GraphQL tools and libraries for development, testing, and monitoring.
Subscribe to my newsletter
Read articles from Wiseland AI Engineering Team directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by