api

How do you choose an API style and API technology when you start a new project?

Today, if you look at API technology research such as RapidAPI Developer Survey and Insights, you’ll probably conclude that REST is the dominant force in the API landscape.

While REST is certainly well-known to most developers and used in a lot of production environments, it may not be the best fit for every scenario. In addition to REST, there’s a few strong API technology options, and each of them has distinct selling points.

Let’s take a look at the Big 3 of API technologies: REST, GraphQL, and gRPC. We won’t dive deep into the way they work; instead, we’ll highlight what’s good and what’s bad about them in various situations. This will hopefully help you make a more informed choice next time you need to create a new API.

REST

REST (REpresentational State Transfer) is the most mature of the 3 API technology options. REST was described way back in 2000 in Roy Fielding’s doctoral dissertation as the core architectural principle of the World Wide Web.

REST can be defined as a stateless, cacheable, convention-based architecture for client-server interaction.

REST aims to follow HTTP semantics closely. It uses URLs to address resources and HTTP verbs (GET, POST, PUT, DELETE, PATCH) to express the action to take.

REST is stateless — the server never stores the client’s state. When the client makes a request, it includes all information necessary for the server to process that request, and resends the information with subsequent requests if needed.

REST requires requests to be cacheable whenever possible, and caching is implemented using HTTP’s native caching headers.

REST is a broad architectural style, as opposed to a concrete API framework or specification, and it leaves a lot of room for interpretation. It doesn’t give you predefined answers to common questions like how to name resources, format JSON requests, include related resources, or implement paging. This ambiguity has led the community to create more specific, opinionated frameworks like JSON:API, HAL, and OData.

Writing HTTP requests to GitHub API and reading responses using JetBrains WebStorm's built-in HTTP Client

Benefits of REST

  • REST has been around for a long time, and it’s very popular in web development. Most developers are at least aware of REST, and a lot of them have hands-on experience using it.
  • Since REST is designed to work with resources, it is a great fit when a domain can be easily described as a set of resources (as opposed to actions). When a domain is described this way, using standard HTTP methods in REST easily enables basic CRUD operations (create, read, update, delete) on all the domain’s data.
  • REST enables intermediate proxy caching that could be useful if your API has stable usage patterns and its traffic is geographically distributed.
  • REST is great for public-facing interfaces: because it’s directly built upon the semantics of HTTP, it’s intuitive for the consumer.

Problems with REST

  • REST is not a great fit for domains where mapping concepts to resources is hard. If you want to send an email, it’s hard to do in a RESTful way as there’s no resource to act upon.
  • REST is prone to underfetching: if you have nested entities — for example, you want to get users along with their comments, — you may need to make multiple requests. Workarounds are available, most prominently the notion of “compound documents” in JSON:API. In addition, using HTTP/2 helps alleviate this problem by reducing handshakes and allowing better compression.
  • There’s also potential for overfetching where if the client only needs a specific piece of data, it will nevertheless receive all the data that the requested endpoint is configured to return. Workarounds are available (e.g. JSON:API’s sparse fieldsets) that allow filtering data in the response, but these workarounds have their own tradeoffs, such as in terms of cacheability.
  • REST can be hard to scale. Teams that need to increase efficiency of data transfer via REST often end up creating more and more endpoints.
  • REST is ambiguous. As solid as Roy Fielding’s doctoral dissertation is, it can’t serve as a specification, and developers tend to interpret REST in different ways.

gRPC

gRPC is Google’s current implementation of the tried and tested RPC (Remote Procedure Call) paradigm where each request is structured like a function call in a programming language. Before being open sourced in 2016, gRPC has evolved from Google’s internal infrastructure where it connected a plethora of large-scale services running across data centers.

gRPC is contract-based: a contract needs to be available on both sides of communication to make sense of data going between them. To define the contracts, gRPC uses a declarative language called Protocol Buffers (Protobuf). Based on a Protobuf contract, gRPC generates compatible client and server code in chosen programming languages.

gRPC provides official libraries for 10+ most popular languages, including C/C++, C#, Java, Kotlin, Python, Go, PHP, and JavaScript (Node.js).

gRPC clients and servers communicate via HTTP/2 using a compact binary format that’s interpreted based on the Protobuf contract. By design, encoding and decoding gRPC messages in any programming language is very efficient.

gRPC supports several types of client-server interaction: the traditional request-response interactions, server streaming (where 1 request from the client may yield multiple responses from the server), and client streaming (multiple requests from the client result in 1 response from the server).

Writing a gRPC API contract in Protobuf using JetBrains Rider

Benefits of gRPC

  • gRPC is focused on performance, which is enabled by a compact data format, fast message encoding and decoding, and the usage of HTTP/2 as the transport layer.
  • Client and server code generation from Protobuf definitions to multiple programming languages helps developers save time on writing boilerplate code and enjoy type safety.
  • gRPC provides better security defaults by virtue of requiring HTTP 2 and TLS/SSL.
  • It provides built-in support for streaming based on HTTP/2 streaming, both unidirectional and bidirectional.
  • gRPC is a perfect fit for frequent interaction between internal services in a microservices architecture.
  • gRPC is also great for collecting data from multiple low-resource agents to a service. IoT devices — smart light switches, cameras, sensors — are perfect examples of such agents.

Problems with gRPC

  • gRPC is currently much less popular than REST, and experienced developers are harder to find.
  • gRPC is not a native solution for customer-facing web applications because it requires HTTP/2, which is not fully supported by browsers. For example, client streaming and bidirectional streaming are not supported in browsers at all. However, there’s a gRPC-Web project that enables using browser-to-backend communication over gRPC without creating a REST proxy.

GraphQL

Introduced by Facebook in 2015, GraphQL represents a different line of API tech evolution. Whereas gRPC focuses on blazing fast service-to-service communication, GraphQL provides an alternative way for browser-based clients to interact with API servers.

GraphQL enables each client to define exactly what shape of data it needs for a particular use case and retrieve all that data in a single roundtrip.

As opposed to REST, GraphQL doesn’t respect the semantics of HTTP verbs: most requests are made with POST. The response from the server matches the format of the request.

GraphQL’s read operations are referred to as queries, and write operations are called mutations. GraphQL requests look very much like a query language.

Selecting data from a GraphQL API using GraphiQL - an in-browser tool for writing, validating, and testing GraphQL queries

Benefits of GraphQL

  • GraphQL is highly flexible in that it allows fetching and delivering exactly what’s required by the client. This approach reduces data transfer overhead.
  • GraphQL actually has a specification, which is definitely a good thing compared to the ambiguity of REST.
  • GraphQL is great for client-server interactions, especially where clients have different data needs. Specifically, it’s a great fit for public APIs if you want to allow customers to request the exact data they want and express complicated queries.
  • GraphQL is a natural choice for APIs that aggregate data from multiple sources for multiple clients. For example, an aggregate GraphQL API could collect internal data by HTTP from microservices and by TCP from databases, and expose this data as JSON optimized for various types of clients.
  • If you’re not sure how your clients are going to use the API that you’re building, GraphQL enables you to avoid defining a strict contract upfront. Instead, you can launch, and then profile real queries to gradually build a picture of what your clients normally need. That’s a good way to deal with uncertainty.
  • GraphQL is best for open querying of large, diverse data sets, and it certainly beats inventing a custom query language for your API.

Problems with GraphQL

  • GraphQL has very limited value for communications between services.
  • Since the client can request any set of data fields at once, the response is as fast as the slowest requested field. This means queries will need to be continuously optimized based on usage patterns.
  • Although client-side and server-side caching can be implemented, GraphQL breaks intermediate proxy caching. This matters when the client and the server are geographically distant. There are several community workarounds that mitigate this, such as making queries via GET and using persisted queries that are pre-computed and stored on the server.

Summary

As you can see, each of the top 3 API technologies has its benefits and drawbacks. Below is a quick decision helper for you to use whenever you need to choose an API technology.

  • Use REST if:
    1. You’re building a CRUD-style web application.
    2. Your API is mostly manipulating well-structured related data.
    3. Your API needs to be highly cacheable, including support for intermediate proxy caching.
  • Use gRPC if:
    1. Your API is private and powers communications between parts of a microservices architecture.
    2. Your API is mostly about actions.
    3. You need to collect data from IoT devices.
    4. You’re implementing a Backend For Frontend pattern for a mobile application with stable API request patterns.
    5. Performance is a critical requirement.
  • Use GraphQL if:
    1. You’re building a public API and you want it to be highly flexible in terms of customizing requests.
    2. You want to defer defining your API surface until you have a chance to analyze which resources your clients tend to request.
    3. You want to aggregate internal data from multiple sources into a public API for multiple clients with varying data requirements.

Last but not least, remember that you don’t have to make a single choice every time: you can mix and match API styles. If your application’s architecture includes multiple APIs for different purposes (such as internal and public-facing APIs), make a separate choice of an API technology for each of these purposes.

Many businesses struggle to discover problems with their cloud services before they impact customers. For developers, writing tests is manual and time-intensive. Speedscale allows you to stress test your cloud services with real-world scenarios. Get confidence in your releases without testing slowing you down. If you would like more information, schedule a demo today!

Longer-Log

Stress test your APIs with real world scenarios.  Collect and replay traffic without scripting.

Newsletter Signup