Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

WHICH API STYLE IS BEST? “” } {

Slide 3

Slide 3 text

THE DEBATE IS STILL RAGING

Slide 4

Slide 4 text

DEBATES MISS THE POINT

Slide 5

Slide 5 text

API DESIGN EVOLUTION? NOT QUITE. RPC REST

Slide 6

Slide 6 text

Coupling Chattiness Client complexity Cognitive complexity Caching Discoverability Versioning MANY DESIGN CONSIDERATIONS } {

Slide 7

Slide 7 text

GOAL: Understand the practical tradeoffs

Slide 8

Slide 8 text

RPC Remote procedure call

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

RPC API EXAMPLE Service definition listConversations(); listMessages(int conversationId); sendMessage(int conversationId, string body);

Slide 11

Slide 11 text

RPC API EXAMPLE Service definition GET /listConversations GET /listMessages?id=123 POST /sendMessage?id=123

Slide 12

Slide 12 text

Get all conversations GET /listConversations [ { "id": 2, "title": "vi or emacs?", "author": 1008 }, ... ] RPC API EXAMPLE

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Reply to conversation POST /sendMessage?id=2 { "body": "Editor debates are silly" } RPC API EXAMPLE

Slide 15

Slide 15 text

Cutting edge of RPC Apache Thrift gRPC Twirp

Slide 16

Slide 16 text

Simple and easy to understand Lightweight payloads High performance ADVANTAGES OF RPC

Slide 17

Slide 17 text

Tight coupling No discoverability Function explosion PROBLEMS WITH RPC

Slide 18

Slide 18 text

/listConversations /listConversationsV2 /listMessages /sendMessage /sendMessageRTL /checkSendStatus /getAuthorDetails /getAuthorDetailsV2 /getFullAuthorDetailsV3 /deleteMessage /deleteMessageAdmin /getTopConversations /getTopConversationsV2 /getSystemStatus FUNCTION EXPLOSION

Slide 19

Slide 19 text

REST Representational state transfer

Slide 20

Slide 20 text

"Here are some resources and what you can do with them" Fundamental unit: resource

Slide 21

Slide 21 text

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" ] } }

Slide 22

Slide 22 text

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" }, ... ]

Slide 23

Slide 23 text

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" }, ... ] }

Slide 24

Slide 24 text

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" } ] } }

Slide 25

Slide 25 text

REST API EXAMPLE Reply to a conversation POST https://api.example.io/conversations/2/messages { "text": "Editor debates are silly" }

Slide 26

Slide 26 text

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" }

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

REST != "RESTful procedure call" REST != JSON over HTTP

Slide 29

Slide 29 text

Hypertext As The Engine Of Application State Goal: decouple the client and server

Slide 30

Slide 30 text

Cutting edge of REST HAL JSON-API Ion

Slide 31

Slide 31 text

Decoupled client and server API can evolve over time Reuses HTTP ADVANTAGES OF REST

Slide 32

Slide 32 text

PROBLEMS WITH REST No single spec Big payloads and "chattiness"

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

GraphQL Graph query language

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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 }

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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" } } ] } ] } }

Slide 39

Slide 39 text

GRAPHQL API EXAMPLE Reply to a conversation mutation { sendMessage(text: "vscode is best") { id } } { "data": { "sendMessage": { "id": "103" } } }

Slide 40

Slide 40 text

Low network overhead Typed schema Fits graph-like data very well ADVANTAGES OF GRAPHQL

Slide 41

Slide 41 text

Complexity Caching Versioning Still early PROBLEMS WITH GRAPHQL

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

THE DEBATE IS STILL RAGING WHICH API STYLE IS BEST? WHO USES MY API?

Slide 44

Slide 44 text

USE CASE: MANAGEMENT API Focus on objects or resources Many varied clients Discoverability and documentation Consider: REST (Ion, HAL, JSON-API)

Slide 45

Slide 45 text

USE CASE: COMMAND API Consider: RPC Action-oriented Simple interactions

Slide 46

Slide 46 text

USE CASE: MICROSERVICES Consider: RPC (gRPC, Twirp) or REST High message rate Low overhead

Slide 47

Slide 47 text

USE CASE: DATA OR MOBILE API Consider: GraphQL Data is graph-like Optimize for high latency

Slide 48

Slide 48 text

NO SILVER BULLET

Slide 49

Slide 49 text

LEARN MORE • YouTube: Les Hazlewood on REST API design • YouTube: Eric Baer on GraphQL • Phil Sturgeon's blog: https://philsturgeon.uk • https://apisyouwonthate.com