A presentation at Nordic APIs Platform Summit 2024 in in Stockholm, Sweden by Rob Allen
GraphQL, REST or RPC? Making the choice! Rob Allen October 2024
APIs can be realised in any style but, which makes the most sense? Rob Allen @akrabat @rob@akrabat.com
RPC APIs Rob Allen @akrabat @rob@akrabat.com
RPC APIs • Call a function on a remote server Rob Allen @akrabat @rob@akrabat.com
RPC APIs • Call a function on a remote server • Common implementations: JSON-RPC, SOAP, gRPC, tRPC Rob Allen @akrabat @rob@akrabat.com
RPC APIs • Call a function on a remote server • Common implementations: JSON-RPC, SOAP, gRPC, tRPC • Tends to require a schema (OpenRPC, WSDL, Protocol Buffer) Rob Allen @akrabat @rob@akrabat.com
JSON-RPC Request: POST / HTTP/1.1 Host: localhost:8545 { “jsonrpc”:”2.0”, “id”:1, “method”:”createUser”, “params”: {“name”: “Rob Allen”, “email: “rob@akrabat.com”} } Rob Allen @akrabat @rob@akrabat.com
JSON-RPC Response: { “jsonrpc”: “2.0”, “id”:1, “result”: {“id”: 1234} } Rob Allen @akrabat @rob@akrabat.com
RESTful APIs Rob Allen @akrabat @rob@akrabat.com
RESTful APIs • Operate on a representation of the state of a resource Rob Allen @akrabat @rob@akrabat.com
RESTful APIs • Operate on a representation of the state of a resource • HTTP native Rob Allen @akrabat @rob@akrabat.com
RESTful APIs • Operate on a representation of the state of a resource • HTTP native • Hypermedia controls Rob Allen @akrabat @rob@akrabat.com
RESTful APIs: Request POST /users/ Content-Type: application/json Accept: application/json { “name”: “Rob Allen” “email”: “rob@akrabat.com” } Rob Allen @akrabat @rob@akrabat.com
RESTful APIs: Response HTTP/1.1 201 Created Content-Type: application/hal+json ETag: dfb9f2ab35fe4d17bde2fb2b1cee88c1 { “name”: “Rob Allen” “email”: “rob@akrabat.com”, “_links”: { “self”: “https://api.example.com/user/1234” } } Rob Allen @akrabat @rob@akrabat.com
GraphQL APIs Rob Allen @akrabat @rob@akrabat.com
GraphQL APIs • Retrieve only the data you need on consumer side Rob Allen @akrabat @rob@akrabat.com
GraphQL APIs • Retrieve only the data you need on consumer side • Reduce the number of calls to retrieve data with embedded resources Rob Allen @akrabat @rob@akrabat.com
GraphQL APIs • Retrieve only the data you need on consumer side • Reduce the number of calls to retrieve data with embedded resources • Self-describing, typed schema Rob Allen @akrabat @rob@akrabat.com
Queries query { author(name: “Anne McCaffrey”) { id, name books(first: 5) { totalCount edges { node { id, title } } } } } Rob Allen @akrabat @rob@akrabat.com
Queries query { author(name: “Anne McCaffrey”) { id, name books(first: 5) { totalCount edges { node { id, title } } } } } Rob Allen @akrabat @rob@akrabat.com
Queries query { author(name: “Anne McCaffrey”) { id, name books(first: 5) { totalCount edges { node { id, title } } } } } Rob Allen @akrabat @rob@akrabat.com
Queries: Result “data”: { “author”: { “id”: “MXxBdXRob3J8ZjA”, “name”: “Anne McCaffrey”, “books”: { “totalCount”: 6, “edges”: [ { “node”: { “id”: “MXxCb29rfGYwNzU”, “title”: “Dragonflight” } }, Rob Allen @akrabat @rob@akrabat.com
Queries: Result “data”: { “author”: { “id”: “MXxBdXRob3J8ZjA”, “name”: “Anne McCaffrey”, “books”: { “totalCount”: 6, “edges”: [ { “node”: { “id”: “MXxCb29rfGYwNzU”, “title”: “Dragonflight” } }, Rob Allen @akrabat @rob@akrabat.com
Queries: Result “data”: { “author”: { “id”: “MXxBdXRob3J8ZjA”, “name”: “Anne McCaffrey”, “books”: { “totalCount”: 6, “edges”: [ { “node”: { “id”: “MXxCb29rfGYwNzU”, “title”: “Dragonflight” } }, Rob Allen @akrabat @rob@akrabat.com
Which to pick? Rob Allen @akrabat @rob@akrabat.com
Lamborghini or Ferrari? Rob Allen @akrabat @rob@akrabat.com
Lamborghini or Truck? Rob Allen @akrabat @rob@akrabat.com
Considerations • What is it to be used for? • Response customisation requirements • HTTP interoperability requirements Rob Allen @akrabat @rob@akrabat.com
What is it to be used for? • Do you control both server and client? • How many users are expected? • What is the skill level of your integrators? Rob Allen @akrabat @rob@akrabat.com
Response customisation • GraphQL is a query-first language • REST tends towards less customisation • With RPC you get what you’re given! Rob Allen @akrabat @rob@akrabat.com
Response customisation • GraphQL is a query-first language • REST tends towards less customisation • With RPC you get what you’re given! (Your data layer’s ability to efficiently retrieve the data is still key!) Rob Allen @akrabat @rob@akrabat.com
Performance • REST and RPC puts server performance first • GraphQL puts client performance first Rob Allen @akrabat @rob@akrabat.com
Caching • RPC, REST and GraphQL can all cache in application layer • REST can additionally cache at HTTP layer Rob Allen @akrabat @rob@akrabat.com
Errors • RPC: Returned payload contains an error object of some form • REST: HTTP semantics; status code • GraphQL: Top level error object for Request errors and Field errors Rob Allen @akrabat @rob@akrabat.com
REST Errors HTTP/1.1 503 Service Unavailable Content-Type: application/problem+json Content-Language: en { “status”: 503, “type”: “https://example.com/service-unavailable”, “title”: “Could not authorise user.”, “detail”: “Auth service is down for maintenance.”, “instance”: “https://example.com/maintenance/2023-05-12”, “error_code”: “AUTHSERVICE_UNAVAILABLE” } Rob Allen @akrabat @rob@akrabat.com
GraphQL Errors “errors”: [ { “message”: “Name for character with ID 7 could not be fetched.”, “path”: [“friends”, 1, “name”] } ], “data”: { “friends”: [ { “id”: “3”, “name”: “F’lar”, “species”: “human”}, { “id”: “7”, “name”: null, “species”: “dragon” }, { “id”: “9”, “name”: “Mnementh”, “species”: “dragon” }, Rob Allen @akrabat @rob@akrabat.com
Versioning • RPC, GraphQL and REST can all version via evolution as easily as each other Rob Allen @akrabat @rob@akrabat.com
Versioning • RPC, GraphQL and REST can all version via evolution as easily as each other • GraphQL is very good for deprecation of specific fields Rob Allen @akrabat @rob@akrabat.com
Design considerations It’s always hard! Rob Allen @akrabat @rob@akrabat.com
Design considerations It’s always hard! Rob Allen @akrabat @rob@akrabat.com
It’s your choice Rob Allen @akrabat @rob@akrabat.com
If you suck at providing a REST API, you will suck at providing a GraphQL API Arnaud Lauret, API Handyman Rob Allen @akrabat @rob@akrabat.com
Thank you! Rob Allen @akrabat @rob@akrabat.com
Photo credits - Choose Pill: https://www.flickr.com/photos/eclib/4905907267 - Lamborghini & Ferrari: https://akrab.at/3w0yFmg - Lamborghini & Truck: https://akrab.at/3F4kAZk Rob Allen @akrabat @rob@akrabat.com
When you’ve been tasked with creating an HTTP API, the fundamental decision you need to make is which architecture to choose. Should your API be RESTful? What about GraphQL? or RPC? In this session, I’ll explain the choices and how each works. We’ll then look at their strengths and weaknesses in order to help guide your decision. By the end of this talk, you’ll be well-placed to choose the right API architecture for your project.