Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

34
Getting Serious with Versioned APIs in Scala Derrick Isaacson, Director of Development

description

Presentation given at JavaOne 2013 by Derrick Isaacson, Director of Development for Lucid Software, makers of Lucidchart. The presentation explains how the uniform interface of REST creates evolvable, versioned APIs. The presentation includes many examples and code snippets using Scala & Play.

Transcript of Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Page 1: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Getting Serious with Versioned APIs in Scala

Derrick Isaacson, Director of Development

Page 2: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Paid

Free

TIE

North

Am

erica

Euro

peAsi

a

Oce

ania

Sout

h Am

erica

Africa

Unkno

wn

0100020003000400050006000700080009000

Hours in editor by region

Page 3: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Evolvability

Page 4: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013
Page 5: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Web Site or Web Service

• Servers return XML• IDs -> more HTTP requests• Auth tokens, caching, content type negotiation• Error status codes –> retries• More XML, JPEG, other formats• Series of rendering steps

Page 6: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

“There is no magic dust that makes an HTTP request a web

service request.”

-Leonard Richardson & Sam Ruby, RESTful Web Services

Page 7: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

What is a “web

service”?

Page 8: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Distributed Computer Architectures

• Distributed memory• RPC services• RESTful services• Distributed file systems• P2P networks• Streaming media

Page 9: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013
Page 10: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013
Page 11: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Extensibility of REST

Fielding DissertationSection 4.1.2

Page 12: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

REST Components

Data Element Modern Web Examples Versioning

resource the intended conceptual target of a hypertext reference

resource identifier URL, URN

representation HTML document, JPEG image

representation metadata media type, last-modified time

control data if-modified-since, cache-control

Page 13: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

1. Evolving the Resource (not the representation!)1. Uniform identification of resources2. Uniform resource manipulation3. Representation separate from the identity4. Hypermedia as the engine of application state5. Self-descriptive messages

Page 14: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

1. Evolving the Resource

http://lucidchart.com/docs/MyHome/v1 http://lucidchart.com/docs/MyHome/v2

Page 15: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

REST Components

Data Element Modern Web Examples Versioning

resource the intended conceptual target of a hypertext reference

URLs

resource identifier URL, URN

representation HTML document, JPEG image

representation metadata media type, last-modified time

control data if-modified-since, cache-control

Page 16: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Evolving the Resource Identifier

1. Uniform identification of resources2. Uniform resource manipulation3. Representation separate from the identity4. Hypermedia as the engine of application state5. Self-descriptive messages

Page 17: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Evolving URLs & Hypermedia

<diagram>

<images>

<image>

<id>123</id>

</image>

</images>

</diagram>

http://lucidchart.com/imgs/123

http://images.lucidchart.com/imgs/123

Page 18: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Evolving URLs & Hypermedia

<diagram>

<images>

<image>

<id>

http://images.lucidchart.com/imgs/123

</id>

</image>

</images>

</diagram>

Page 19: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Evolving URLs & Uniform Response Codes

http://lucidchart.com/imgs/123 http://images.lucidchart.com/imgs/123

200 OK

<response>

<status>Error</status>

<msg>Not Found</msg>

</response>

404 Not Found

<userMsg>

</userMsg>

301 Moved Permanently

Location: http://images...

fail

Page 20: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Hypermedia with Scala & Play

#routes

GET /users/{id} lucid.getUser(id)

def getUser(id: Int) = {

val accountURI =

routes.App.userAccount(id)

val template = User(accountURI)

Ok(template)

}

Page 21: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

2. Evolving URLs with Scala & Play

# Images moved permanently

GET /imgs/{id} lucid.redirectImages(id)

def redirectImages(id: Int) = {

val location =

“http://images.lucidchart.com/images/”+id

Redirect(location)

}

Page 22: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

REST Components

Data Element Modern Web Examples Versioning

resource the intended conceptual target of a hypertext reference

URLs

resource identifier URL, URN Hypermedia & Uniform Status Codes

representation HTML document, JPEG image

representation metadata media type, last-modified time

control data if-modified-since, cache-control

Page 23: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

3. Self-descriptive Messages

GET /users/123 HTTP 1.1

Host: example.com

User-Agent: XYZ 1.1

Accept: text/html, application/xhtml+xml, application/xml

Keep-Alive: 300

Connection: keep-alive

If-Modified-Since: Fri, 02 Sep 2013 16:47:31 GMT

If-None-Match: "600028c-59fb-474f6852c9dab"

Cache-Control: max-age=60

Date: Fri, 02 Sep 2013 16:47:31 GMT

Via: 1.0, myproxy, 1.1 lucidchart.com (Apache/1.1)

Authorization: Bearer mF_9.B5f-4.1JqM

Page 24: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

3. Self-descriptive Messages

HTTP/1.1 200 OK

Date: Sun, 04 Oct 2013 19:36:25 GMT

Server: Apache/2.2.11 (Debian)

Last-Modified:Fri, 02 Oct 2013 16:48:39 GMT

Etag: "600028c-59fb-474f6852c9dab"

Cache-Control: max-age=300

Accept-Ranges: bytes

Vary: Accept-Encoding

Content-Type: application/xml

Content-Encoding: gzip

Content-Length: 7160

Keep-Alive: timeout=15,max=91

Connection: Keep-Alive

Page 25: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

3. Evolving Resource Metadata & Control Data1. Uniform identification of resources2. Uniform resource manipulation3. Representation separate from the identity4. Hypermedia as the engine of application state5. Self-descriptive messages

Page 26: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

REST Components

Data Element Modern Web Examples Versioning

resource the intended conceptual target of a hypertext reference

URLs

resource identifier URL, URN Hypermedia & Uniform Status Codes

representation HTML document, JPEG image

representation metadata

media type, last-modified time

Self-descriptive w/ Uniform Headers

control data if-modified-since, cache-control

Page 27: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

4. Evolving RepresentationsGET /images/123

200 OK HTTP 1.1

Content-Type: application/xml

<response>

<status>success</status>

<id>123</id>

<image>MTIzNmEyMTM…=</image>

</response>

GET /images/123

Accept: image/jpeg

200 OK HTTP 1.1

Content-Type: image/jpeg

(jpeg image)

Page 28: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

4. Evolving Representations

Standard media types!

http://microformats.org/

http://www.iana.org/assignments/media-types

Page 29: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

GET /users/123

{

name: “John Smith”,

phone: “000-000-0000”,

email: “[email protected]”,

photo: “YWZzYSAyMzR2NQzJ2dzLmZhc20uLC8uLA==“,

groups: [ { id: 234, name: “Team A”, members: […] }, … ],

account: { id: 345, company: “Big Enterprise”, …},

books: [

{ id: 456, name: “RESTful Web Services”, publishDate: … },

{ id: 567, name: “REST in Practice”, … },

],

{

name: “John Smith”,

phone: “000-000-0000”,

email: “[email protected]”,

photo: “https://lucidchart.com/images/abc“,

groups: “https://lucidchart.com/groups?user=123”

account: “https://lucidchart.com/”,

books: “https://books.example.com/catalog?ids=456…”,

}

Page 30: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

4. Custom Media Types

GET /diagrams/v1/123 HTTP/1.1…

GET /diagrams/v1/123… X

Page 31: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

4. Custom Media Types

GET /diagrams/123 HTTP/1.1

Accept: application/vnd.lucid.diagram+xml

GET /diagrams/123 HTTP/1.1

Accept: application/vnd.lucid.diagram-v2+xml…

Page 32: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

REST Components

Data Element Modern Web Examples Versioning

resource the intended conceptual target of a hypertext reference

URLs

resource identifier URL, URN Hypermedia & Uniform Status Codes

representation HTML document, JPEG image Content-type header, uniform media types, and general uniform interface

representation metadata

media type, last-modified time

Self-descriptive w/ Uniform Headers

control data if-modified-since, cache-control

Page 33: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

“The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components. By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved. Implementations are decoupled from the services they provide, which encourages independent evolvability.”

Page 34: Scaling Web Services with Evolvable RESTful APIs - JavaOne 2013

Q & A

http://www.lucidchart.com/jobs