REST vs GraphQL APIs, the Good, the Bad, the Ugly

Since being introduced by Facebook, GraphQL has taken the API world by storm as an alternative to REST APIs. GraphQL fixes many problems that API developers and users have found with RESTful architecture. However, it also introduces a new set of challenges which need to be evaluated. Because GraphQL is not simply a evolutionary replacement for REST, this post will deep dive into the pros and cons of each and when GraphQL makes sense for your application.

History

Before RESTful APIs, we had RPC, SOAP, CORBA, and other less open protocols. Many pre-REST APIs required complex client libraries to serialize/deserialize the payload over the wire. A fundamental difference compared to today’s RESTful APIs, is that SOAP is strongly typed using formal contracts via WSDL (Web Services Description Language). This could wreck havoc on interoperability since even removing a 32-bit integer restriction to accepting a 64-bit long meant breaking upstream clients. SOAP is not an architecture, but a full protocol implementation consisting of security, error handling, ACID transactions, etc Some of the complexity is due to many abstraction layers baked into SOAP. For example, SOAP is able to run on HTTP, TCP, UDP, etc. While the protocol implementation afforded much abstraction, the application and data layer’s rigid contract between the client and server created a tight coupling between the two.

RESTful architecture was introduced in 2000 as a much simpler way to enable machine to machine communication using only the ubiquitous HTTP protocol without additional layers in a stateless and type free way. This enabled systems to be loosely coupled and more forgiving to contract changes between systems such as between companies.

REST today

REST APIs have become the de facto standard for companies deploying APIs and launching developer platforms. The beauty of REST is that a developer working with someone else’s API doesn’t need any special initialization or libraries. Requests can be simply sent via common software like cURL and web browsers.

REST uses the standard CRUD HTTP Verbs (GET, POST, PUT, DELETE) and leverages HTTP conventions and centered around data resources (HTTP URIs) rather than attempting to fight HTTP. Thus an e-commerce with a resource api.acmestore.com/items can behave similar to a bank with a resource api.examplebank.com/deposits. Both would probably need CRUD operations on that resource and prefer to cache queries (i.e. both GET api.acmestore.com/items and GET api.examplebank.com/transactions would be cached). 3rd party developers to a new API need to only reason about the data model and leave the rest to HTTP convention rather than digging deep into thousands of operations. In other words, REST is much tighter coupled to HTTP and CRUD compared to SOAP, but provides loose data contracts.

Problems with REST

As more variety of APIs are placed in production use and scaled to extreme levels, certain problems in RESTful architecture transpired. You could even say GraphQL is between SOAP and REST taking pieces from each.

Server driven selection

In RESTful APIs, the server creates the representation of a resource to be responded back to a client.

However, what if the client wants something specific such as return the names of friends of friends of a user where their job is engineer.

With REST, you might have something like:

GET api.example.com/users/123?include=friend.friend.name&friend.friend.ocupation=engineer

GraphQL allows you to represent this query in a cleaner way:

{
 user(id: 123) {
   friends {
     friends(job: "engineer") {
       name
     }
   }
 }
}

Fetching multiple resources

One of the main benefits of GraphQL is to make APIs less chatty. Many of us have seen an API where we first have to GET /user first and then fetch each friend individually via GET /user/:id/friend/:id endpoint, this can result in N+1 queries and is a will known performance issue in API and database queries. In other words, RESTful API calls are chained on the client before the final representation can be formed for display. GraphQL can reduce this by enabling the server to aggregate the data for the client in a single query.

More in depth analytics

While API analytics is also a negative for GraphQL apis since there is very little tooling out there. The tools that do support GraphQL APIs can provide much more insights into queries than RESTful APIs.

Problems with GraphQL

Caching

Caching is built into in the HTTP specification which RESTful APIs are able to leverage. GET vs POST semantics related to caching are well defined enabling browser caches, intermediate proxies, and server frameworks to follow. The following guidelines can be followed:

  • GET requests can be cached
  • GET requests can stay in browser history
  • GET requests can be bookmarked
  • GET requests are idempotent

GraphQL doesn’t follow the HTTP spec for caching and instead uses a single endpoint. Thus, it’s up to the developer to ensure caching is implemented correctly for non-mutable queries that can be cached. The correct key has to be used for the cache which may include inspecting the body contents.

While you can use tools like Relay or Dataloader that understands GraphQL semantics, that still doesn’t cover things like browser and mobile caching.

Diminishes shared nothing architecture

The beauty of RESTful APIs is that they complement shared nothing architecture well. For example, Moesif has a api.moesif.com/v1/search endpoint and a api.moesif.com/v1/alerting endpoint. Publicly, those two endpoints simply look like two different REST resources. Internally though, they point to two different microservices on isolated compute clusters. The search service is written in Scala and the alerting service is written in NodeJS. The complexity in routing HTTP requests via host or URL is much lower than inspecting a GraphQL query and performing multiple joins.

Exposed for arbitrary requests

While a main benefit of GraphQL is to enable clients to query for just the data they need, this can also be problematic especially for open APIs where an organization cannot control 3rd party client query behavior. Great care has to be taken to ensure GraphQL queries don’t result in expensive join queries that can bring down server performance or even DDoS the server. RESTful APIs can be constrained to match data model and indexing used.

Rigidness of queries

GraphQL removes the ability for custom query DSLs or side effect operations on top of an API. For example, the Elasticsearch API is RESTful, but also has a very powerful Elasticsearch DSL to perform advanced aggregations and metric calculations. Such aggregation queries may be harder to model within the GraphQL language.

Non existent monitoring

RESTful APIs have the benefit of following the HTTP spec with regards to resources just like a website. This enables many tools to probe a URL such as api.moesif.com/health which would return 5xx if not OK. For GraphQL APIs, you may not be able to leverage such tools unless you support placing the query as a URL parameter as most ping tools don’t support HTTP and request bodies.

Besides ping services, there are very few SaaS or open source tools that support API analytics or deeper analysis of your API calls. Client errors are presented as a 200 OK in a GraphQL API. Existing tools that expect 400 errors will not work so you may miss errors happening on your API. Yet at the same time, more flexibility given to the client requires even more tools to catch and understand problems with your API.

What is Moesif? Moesif is the most advanced REST and GraphQL analytics platform used by Thousands of platformsto measure how your queries are performing and understand what your most loyal customers are doing with your APIs.

Conclusion

GraphQL APIs can be exciting new technology, but it is important to understand the tradeoffs before making such architectural decisions. Some APIs such as those with very few entities and relationships across entities like analytics APIs may not be suited for GraphQL. Whereas applications with many different domain objects like e-commerce where you have items, users, orders, payments, and so on may be able to leverage GraphQL much more.

In fact, GraphQL vs REST is like comparing SQL technologies vs noSQL. There are certain applications where it makes sense to model complex entities in a SQL Db. Whereas other apps that only have “messages” as in high volume chat apps or analytics APIs where the only entity is an “event” may be more suited using something like Cassandra.

Learn More About Moesif Monitor REST And GraphQL APIs With Moesif 14 day free trial. No credit card required. Learn More
Monitor REST And GraphQL APIs With Moesif Monitor REST And GraphQL APIs With Moesif

Monitor REST And GraphQL APIs With Moesif

Learn More