+ All Categories
Home > Software > Extend your REST API

Extend your REST API

Date post: 15-Apr-2017
Category:
Upload: alexey-tokar
View: 100 times
Download: 0 times
Share this document with a friend
38
One API to serve them all for free. no SMS, no registration Alexey Tokar Head of Development @ WorldApp
Transcript
Page 1: Extend your REST API

One API to serve them allfor free. no SMS, no registration

Alexey Tokar

Head of Development @ WorldApp

Page 2: Extend your REST API

What this talk is not about

2

Page 3: Extend your REST API

HTTP method semantics

GET - for listPOST - for create

PATCH - for partial updateDELETE - for delete

PUT - for update3

Page 4: Extend your REST API

Resources name convention

/programmer/42VS

/programmers/424

Page 5: Extend your REST API

HTTP status code meaning

1xx Informational2xx Success3xx Redirection4xx Client Error5xx Server Error

5

Page 6: Extend your REST API

HATEoAS architecture

Hypermedia

as the

Engine

of

Application

State

6

Page 7: Extend your REST API

What we are going to coverDifferent devices and environmentsApplication and API designReal behavior of services and our expectations

7

Page 8: Extend your REST API

What our goals are?Blazing fast processing and respondingAwesome stability and expected behaviorLimitless scalability Tremendous flexibility in operation and support

8

Page 9: Extend your REST API

Two major API design

9

Page 10: Extend your REST API

N device types : N APIs

10

Page 11: Extend your REST API

Pros & consEasy to manageOptimized for deviceSimple codebase

11

Exponential diversityHard to deployLong way to fix

Page 12: Extend your REST API

N device types : 1 API

12

Page 13: Extend your REST API

Pros & consEasy to manageOptimized for deviceSimple codebaseEasy to deployShort way to fixLinear diversity :)

13

Reduced flexibility

Page 14: Extend your REST API

One API to serve them all

14

Page 15: Extend your REST API

We don’t need that sheet!

15

Page 16: Extend your REST API

Please welcome our resources!GET /posts/1{

id : "/posts/1",

title : "title",

created: "2016-10-16T10:00:00Z",

author : {

href: "/users/2"

},

similar: {

href: "/posts/1/similar"

}

}

GET /users/2{

id : "/users/2",

name: "alexey",

dob: "1986-08-14"

}

16Looks like HATEoAS

Page 17: Extend your REST API

We need only part of your Data

17

Page 18: Extend your REST API

Did you know...1 Twitter post thought REST API takes about 5KiBTransferring 20KiB over 3G will last approximately

20ms

Average type speed is 120wpm for keyboards and 30wpm for mobile devices* (100ms and 400ms per character)

Even level 1 gzip could save up to x15 of your REST API traffic 18

* http://www.pocketables.com/archives/mobile-device-keyboard

Page 19: Extend your REST API

?fields=<fieldsList>GET /posts/1?fields=title,id{

id : "/posts/1",

title : "title"

}

19http://drawingimage.com/files/1/Llama-Realistic-Drawing.jpg

Page 20: Extend your REST API

Ordinary Service could look like

@Serviceclass UserService { public User find( String id, Set<Field> fields ) { //... }}

20

Page 21: Extend your REST API

LimitationsViolation of the IoC principleHard to manage consistency of new servicesNeed to rewrite all the codebase

21

Page 22: Extend your REST API

Possible data path

22

Page 23: Extend your REST API

Easy to manage solutionList<String> fields = Arrays.asList( "id", "title" );

ObjectMapper mapper = new ObjectMapper();JsonNode tree = mapper.readTree( response );

Iterator<Map.Entry<String, JsonNode>> it = tree.fields();while ( it.hasNext() ) { Map.Entry<String, JsonNode> entry = it.next(); String key = entry.getKey(); if ( !fields.contains( key ) ) { it.remove(); }}

23

Page 24: Extend your REST API

Give us all we need

24

Page 25: Extend your REST API

Different data on a page

25

Page 26: Extend your REST API

Optimal solutions

26

SPDY

HTTP/2With multiplexing

HTTP 1.1With keep-alive

Page 27: Extend your REST API

How Big Guys do it?POST /batch HTTP/1.1Authorization: Bearer your_auth_tokenHost: www.googleapis.comContent-Type: multipart/mixed; boundary=batch_foobarbazContent-Length: total_content_length

--batch_foobarbazContent-Type: application/httpGET /farm/v1/animals/pony

--batch_foobarbazContent-Type: application/httpGET /farm/v1/animals--batch_foobarbaz-- 27

Page 28: Extend your REST API

Semantically correctvs

Hard to use

28

Page 29: Extend your REST API

/batchPOST /batch{

myProfile : "/users/me",

post : "/posts/1?fields=id,author,href"

}

{

myProfile : {

id : "/users/2",

name: "alexey",

dob: "1986-08-14"

},

post : {

id : "/posts/1",

author : {

href: "/users/2"

}

}

}29

Page 30: Extend your REST API

Simple data proxyObjectNode tree = mapper.createObjectNode();

for ( Map.Entry<String, String> nameToUrl : map.entrySet() ) { tree.set( nameToUrl.getKey(), mapper.readTree( new URL( request.getScheme(), request.getServerName(), request.getServerPort(), nameToUrl.getValue() ) ) );}

30

Page 31: Extend your REST API

Please, be so kind to include relations

31

Page 32: Extend your REST API

Data related to main content

32

Page 33: Extend your REST API

?include=<subObject>GET /posts/1?include=author{

id : "/posts/1",

title : "title",

created: "2016-10-16T10:00:00Z",

author : {

id : "/users/2",

name: "alexey",

dob: "1986-08-14"

},

similar: {

href: "/posts/1/similar"

}

} 33

GET /posts/1{

id : "/posts/1",

title : "title",

created: "2016-10-16T10:00:00Z",

author : {

href: "/users/2"

},

similar: {

href: "/posts/1/similar"

}

}

Page 34: Extend your REST API

Altogether!POST /batch{

part1 : “/resource/24

? include=some,sub,resource

& fields=only,what,you,need”

}

34

Page 35: Extend your REST API

Why it’s a good solution?Only one set of resourcesAsynchronization on the backendOnly one HTTP request per screen with only needed

dataScalable and manageable solutionSingle entrance and exit pointSimple services, dao and dtoCould be adapted to any* existing API

35

Page 36: Extend your REST API

Right questionsWhy you are not using Protobuf or Flatbuffers?

Good json serialization library + gzip + etag negate the difference. Also JSON is still the most popular data format for APIs.

You are talking about performance but still make heavy DB queries.

Yes, but this is a tradeoff for simplification and ease of support. We still could serve 10K+ rps per node.

Why internal dispatching is more preferable than custom monster-join approach?

It is simpler to add more servers for our services and tweak performance that way instead of trying to fix each complex-query performance. But this is another discussable tradeoff :)

36

Page 37: Extend your REST API

37

https://github.com/alexeytokar/rainbow-rest

Page 38: Extend your REST API

Questions?Alexey Tokar

Head of Development @ WorldApp

38


Recommended