API throwdown: RPC vs. REST vs. GraphQL

API throwdown: RPC vs. REST vs. GraphQL

Choosing an API design paradigm can be hard. The colorful debates on Twitter about which API style is "best" make it even harder. In this talk, I break down the three popular styles today (RPC, REST, GraphQL), weigh their strengths and weaknesses, and discuss when each makes sense.

3662c6afc9e95019ec22a44410fa226f?s=128

Nate Barbettini

March 08, 2018
Tweet

Transcript

  1. RPC VS. REST VS. GraphQL February 27, 2018 An API

    throwdown
  2. WHICH API STYLE IS BEST? “” } {

  3. THE DEBATE IS STILL RAGING

  4. DEBATES MISS THE POINT

  5. API DESIGN EVOLUTION? NOT QUITE. RPC REST

  6. Coupling Chattiness Client complexity Cognitive complexity Caching Discoverability Versioning MANY

    DESIGN CONSIDERATIONS } {
  7. GOAL: Understand the practical tradeoffs

  8. RPC Remote procedure call

  9. "Call a function on another server" Fundamental unit: function

  10. RPC API EXAMPLE Service definition listConversations(); listMessages(int conversationId); sendMessage(int conversationId,

    string body);
  11. RPC API EXAMPLE Service definition GET /listConversations GET /listMessages?id=123 POST

    /sendMessage?id=123
  12. Get all conversations GET /listConversations [ { "id": 2, "title":

    "vi or emacs?", "author": 1008 }, ... ] RPC API EXAMPLE
  13. Get all messages in a conversation GET /listMessages?id=2 [ {

    "id": 100, "message": "Atom", "author": 3001 }, { "id": 101, "message": "Real programmers use Notepad.", "author": 3009 } ] RPC API EXAMPLE
  14. Reply to conversation POST /sendMessage?id=2 { "body": "Editor debates are

    silly" } RPC API EXAMPLE
  15. Cutting edge of RPC Apache Thrift gRPC Twirp

  16. Simple and easy to understand Lightweight payloads High performance ADVANTAGES

    OF RPC
  17. Tight coupling No discoverability Function explosion PROBLEMS WITH RPC

  18. /listConversations /listConversationsV2 /listMessages /sendMessage /sendMessageRTL /checkSendStatus /getAuthorDetails /getAuthorDetailsV2 /getFullAuthorDetailsV3 /deleteMessage

    /deleteMessageAdmin /getTopConversations /getTopConversationsV2 /getSystemStatus FUNCTION EXPLOSION
  19. REST Representational state transfer

  20. "Here are some resources and what you can do with

    them" Fundamental unit: resource
  21. REST API EXAMPLE Entry point GET https://api.example.io/ { "conversations": {

    "href": "https://api.example.io/conversations", "rel": [ "collection" ], "desc": "View all conversations" }, "messages:" { "href": "https://api.example.io/messages", "rel": [ "collection" ] } }
  22. REST API EXAMPLE Get all conversations GET https://api.example.io/conversations { "count":

    2, "value": [ { "href": "https://api.example.io/conversations/2", "title": "vim or emacs?", "author": "https://api.example.io/users/1008", "messages": "https://api.example.io/conversations/2/messages" }, ... ]
  23. REST API EXAMPLE Get all messages in a conversation GET

    https://api.example.io/conversations/2/messages { "count": 3, "value": [ { "href": "https://api.example.io/messages/101", "conversation": "https://api.example.io/conversations/2", "text": "Real programmers use Notepad.", "author": "https://api.example.io/users/3009" }, ... ] }
  24. REST API EXAMPLE Describe operations on resources "create": { "href":

    "https://api.example.io/conversations/2/messages", "method": "POST", "desc": "Reply to conversation", "value": [ { "name": "text", "desc": "Your reply" } ] } }
  25. REST API EXAMPLE Reply to a conversation POST https://api.example.io/conversations/2/messages {

    "text": "Editor debates are silly" }
  26. REST API EXAMPLE Get author info GET https://api.example.io/users/3009 { "href":

    "https://api.example.io/users/3009", "name": "Joe Brogrammer", "location": "None of your business", "messages": { "href": "https://api.example.io/users/3009/messages", "rel" [ "collection" ], "desc": "View user's messages" }
  27. REST API EXAMPLE Get recent conversations + replies + authors

    GET https://api.example.io/conversations GET https://api.example.io/conversations/1 GET https://api.example.io/conversations/1/messages GET https://api.example.io/users/214 GET https://api.example.io/conversations/2 GET https://api.example.io/conversations/2/messages GET https://api.example.io/users/3009
  28. REST != "RESTful procedure call" REST != JSON over HTTP

  29. Hypertext As The Engine Of Application State Goal: decouple the

    client and server
  30. Cutting edge of REST HAL JSON-API Ion

  31. Decoupled client and server API can evolve over time Reuses

    HTTP ADVANTAGES OF REST
  32. PROBLEMS WITH REST No single spec Big payloads and "chattiness"

  33. REST API "CHATTINESS" GET https://api.example.io/conversations GET https://api.example.io/conversations/1 GET https://api.example.io/conversations/1/messages GET

    https://api.example.io/users/214 GET https://api.example.io/conversations/2 GET https://api.example.io/conversations/2/messages GET https://api.example.io/users/3009
  34. GraphQL Graph query language

  35. "Ask for exactly what you want" Fundamental unit: query

  36. GRAPHQL API EXAMPLE Schema definition type Query { listConversations: [Conversation]

    } type Mutation { sendMessage(text: String): Message } type Conversation { id: Int title: String messages: [Message] } type Message { id: ID text: String author: User } type User { id: ID name: String }
  37. GRAPHQL API EXAMPLE Get all conversations and messages { listConversations

    { title, messages { text } } } { "data": { "listConversations": [ { "title": "vim or emacs?", "messages": [ { "text": "Real programmers use Notepad." } ] } ] } }
  38. GRAPHQL API EXAMPLE Get all conversations + messages + author

    names { listConversations { title, messages { text, author { name } } } } { "data": { "listConversations": [ { "title": "vim or emacs?", "messages": [ { "text": "Real programmers use Notepad." "author": { "name": "Joe Brogrammer" } } ] } ] } }
  39. GRAPHQL API EXAMPLE Reply to a conversation mutation { sendMessage(text:

    "vscode is best") { id } } { "data": { "sendMessage": { "id": "103" } } }
  40. Low network overhead Typed schema Fits graph-like data very well

    ADVANTAGES OF GRAPHQL
  41. Complexity Caching Versioning Still early PROBLEMS WITH GRAPHQL

  42. Coupling Chattiness Client complexity Cognitive complexity Caching Discoverability Versioning RPC

    Functions ▪ High ▪ Medium ▪ Low ▪ Low ▪ Custom ▪ Bad ▪ Hard REST Resources ▪ Low ▪ High ▪ Medium ▪ Low ▪ HTTP ▪ Good ▪ Easy GraphQL Queries ▪ Medium ▪ Low ▪ High ▪ High ▪ Custom ▪ Good ??? DESIGN CONSIDERATIONS
  43. THE DEBATE IS STILL RAGING WHICH API STYLE IS BEST?

    WHO USES MY API?
  44. USE CASE: MANAGEMENT API Focus on objects or resources Many

    varied clients Discoverability and documentation Consider: REST (Ion, HAL, JSON-API)
  45. USE CASE: COMMAND API Consider: RPC Action-oriented Simple interactions

  46. USE CASE: MICROSERVICES Consider: RPC (gRPC, Twirp) or REST High

    message rate Low overhead
  47. USE CASE: DATA OR MOBILE API Consider: GraphQL Data is

    graph-like Optimize for high latency
  48. NO SILVER BULLET

  49. LEARN MORE • YouTube: Les Hazlewood on REST API design

    • YouTube: Eric Baer on GraphQL • Phil Sturgeon's blog: https://philsturgeon.uk • https://apisyouwonthate.com