YOU ARE DOWNLOADING DOCUMENT

Please tick the box to continue:

Transcript
Page 1: Design Beautiful REST + JSON APIs

Beautiful REST + JSON APIs

Les Hazlewood @lhazlewoodCTO, Stormpathstormpath.com

Page 2: Design Beautiful REST + JSON APIs

.com

• Identity Management andAccess Control API

• Security for your applications• User security workflows• Security best practices• Developer tools, SDKs, libraries

Page 3: Design Beautiful REST + JSON APIs

Outline• APIs, REST & JSON• REST Fundamentals• Design

Base URLVersioningResource FormatReturn ValuesContent NegotiationReferences (Linking)PaginationQuery ParametersAssociations

ErrorsIDsMethod OverloadingResource ExpansionPartial ResponsesCaching & EtagsSecurityMulti TenancyMaintenance

Page 4: Design Beautiful REST + JSON APIs

APIs

• Applications• Developers• Pragmatism over Ideology• Adoption• Scale

Learn more at Stormpath.com

Page 5: Design Beautiful REST + JSON APIs

Why REST?

• Scalability• Generality• Independence• Latency (Caching)• Security• Encapsulation

Learn more at Stormpath.com

Page 6: Design Beautiful REST + JSON APIs

Why JSON?

• Ubiquity• Simplicity• Readability• Scalability• Flexibility

Learn more at Stormpath.com

Page 7: Design Beautiful REST + JSON APIs

HATEOAS

• Hypermedia

• As

• The

• Engine

• Of

• Application

• State

Further restriction on REST architectures.Learn more at Stormpath.com

Page 8: Design Beautiful REST + JSON APIs

REST Is Easy

Learn more at Stormpath.com

Page 9: Design Beautiful REST + JSON APIs

REST Is *&@#$! Hard(for providers)

Learn more at Stormpath.com

Page 10: Design Beautiful REST + JSON APIs

REST can be easy

(if you follow some guidelines)

Learn more at Stormpath.com

Page 11: Design Beautiful REST + JSON APIs

Example Domain: Stormpath

• Applications• Directories• Accounts• Groups• Associations• Workflows

Page 12: Design Beautiful REST + JSON APIs

Fundamentals

Learn more at Stormpath.com

Page 13: Design Beautiful REST + JSON APIs

Resources

Nouns, not Verbs

Coarse Grained, not Fine Grained

Architectural style for use-case scalability

Learn more at Stormpath.com

Page 14: Design Beautiful REST + JSON APIs

What If?/getAccount

/createDirectory

/updateGroup

/verifyAccountEmailAddress

Learn more at Stormpath.com

Page 15: Design Beautiful REST + JSON APIs

What If?/getAccount/getAllAccounts/searchAccounts/createDirectory/createLdapDirectory/updateGroup/updateGroupName/findGroupsByDirectory/searchGroupsByName/verifyAccountEmailAddress/verifyAccountEmailAddressByToken…Smells like bad RPC. DON’T DO THIS.Learn more at Stormpath.com

Page 16: Design Beautiful REST + JSON APIs

Keep It Simple

Learn more at Stormpath.com

Page 17: Design Beautiful REST + JSON APIs

The Answer

Fundamentally two types of resources:

Collection Resource

Instance Resource

Learn more at Stormpath.com

Page 18: Design Beautiful REST + JSON APIs

Collection Resource

/applications

Learn more at Stormpath.com

Page 19: Design Beautiful REST + JSON APIs

Instance Resource

/applications/a1b2c3

Learn more at Stormpath.com

Page 20: Design Beautiful REST + JSON APIs

Behavior• GET• PUT• POST• DELETE• HEAD

Learn more at Stormpath.com

Page 21: Design Beautiful REST + JSON APIs

Behavior

POST, GET, PUT, DELETE

≠ 1:1Create, Read, Update, Delete

Learn more at Stormpath.com

Page 22: Design Beautiful REST + JSON APIs

Behavior

As you would expect:

GET = ReadDELETE = DeleteHEAD = Headers, no Body

Learn more at Stormpath.com

Page 23: Design Beautiful REST + JSON APIs

Behavior

Not so obvious:

PUT and POST can both be used forCreate and Update

Learn more at Stormpath.com

Page 24: Design Beautiful REST + JSON APIs

PUT for Create

Identifier is known by the client:

PUT /applications/clientSpecifiedId

{ …}

Learn more at Stormpath.com

Page 25: Design Beautiful REST + JSON APIs

PUT for Update

Full Replacement

PUT /applications/existingId{ “name”: “Best App Ever”, “description”: “Awesomeness”}

Learn more at Stormpath.com

Page 26: Design Beautiful REST + JSON APIs

PUT

Idempotent

Learn more at Stormpath.com

Page 27: Design Beautiful REST + JSON APIs

POST as CreateOn a parent resource

POST /applications{ “name”: “Best App Ever”}

Response:

201 CreatedLocation: https://api.stormpath.com/applications/a1b2c3

Learn more at Stormpath.com

Page 28: Design Beautiful REST + JSON APIs

POST as UpdateOn instance resource

POST /applications/a1b2c3

{ “name”: “Best App Ever. Srsly.”}

Response:

200 OK

Learn more at Stormpath.com

Page 29: Design Beautiful REST + JSON APIs

POST

NOT Idempotent

Learn more at Stormpath.com

Page 30: Design Beautiful REST + JSON APIs

Media Types

• Format Specification + Parsing Rules• Request: Accept header• Response: Content-Type header

• application/json• application/foo+json• application/foo+json;application• …

Learn more at Stormpath.com

Page 31: Design Beautiful REST + JSON APIs

Design Time!

Learn more at Stormpath.com

Page 32: Design Beautiful REST + JSON APIs

Base URL

Learn more at Stormpath.com

Page 33: Design Beautiful REST + JSON APIs

http(s)://api.foo.com

vs

http://www.foo.com/dev/service/api/rest

Learn more at Stormpath.com

Page 34: Design Beautiful REST + JSON APIs

http(s)://api.foo.com

Rest Clientvs

Browser

Learn more at Stormpath.com

Page 35: Design Beautiful REST + JSON APIs

Versioning

Learn more at Stormpath.com

Page 36: Design Beautiful REST + JSON APIs

URL https://api.stormpath.com/v1

vs.

Media-Type application/foo+json;application&v=1

Learn more at Stormpath.com

Page 37: Design Beautiful REST + JSON APIs

Resource Format

Learn more at Stormpath.com

Page 38: Design Beautiful REST + JSON APIs

Media Type

Content-Type: application/json

When time allows:

application/foo+jsonapplication/foo+json;bar=baz&v=1…

Learn more at Stormpath.com

Page 39: Design Beautiful REST + JSON APIs

camelCase

‘JS’ in ‘JSON’ = JavaScript

myArray.forEach Not myArray.for_each

account.givenNameNot account.given_name

Underscores for property/function names are unconventional for JS. Stay consistent.

Learn more at Stormpath.com

Page 40: Design Beautiful REST + JSON APIs

Date/Time/Timestamp

There’s already a standard. Use it: ISO 8601

Example:

{ …, “createdTimestamp”: “2012-07-10T18:02:24.343Z”}

Use UTC!

Learn more at Stormpath.com

Page 41: Design Beautiful REST + JSON APIs

Response Body

Learn more at Stormpath.com

Page 42: Design Beautiful REST + JSON APIs

GET obvious

What about POST?

Return the representation in the response when feasible.

Add override (?_body=false) for control

Learn more at Stormpath.com

Page 43: Design Beautiful REST + JSON APIs

Content Negotiation

Learn more at Stormpath.com

Page 44: Design Beautiful REST + JSON APIs

Header

• Accept header

• Header values comma delimited in order of preference

GET /applications/a1b2c3Accept: application/json, text/plain

Learn more at Stormpath.com

Page 45: Design Beautiful REST + JSON APIs

Resource Extension

/applications/a1b2c3.json/applications/a1b2c3.csv…

Conventionally overrides Accept header

Learn more at Stormpath.com

Page 46: Design Beautiful REST + JSON APIs

HREF

• Distributed Hypermedia is paramount!

• Every accessible Resource has a canonical unique URL

• Replaces IDs (IDs exist, but are opaque).

• Critical for linking, as we’ll soon see

Learn more at Stormpath.com

Page 47: Design Beautiful REST + JSON APIs

Instance w/ HREF (v1)

GET /accounts/x7y8z9

200 OK{ “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “givenName”: “Tony”, “surname”: “Stark”, ...}

Learn more at Stormpath.com

Page 48: Design Beautiful REST + JSON APIs

Resource Referencesaka ‘Linking’

(v1)

Learn more at Stormpath.com

Page 49: Design Beautiful REST + JSON APIs

• Hypermedia is paramount. • Linking is fundamental to scalability.

• Tricky in JSON• XML has it (XLink), JSON doesn’t• How do we do it?

Learn more at Stormpath.com

Page 50: Design Beautiful REST + JSON APIs

Instance Reference (v1)

GET /accounts/x7y8z9

200 OK{ “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “givenName”: “Tony”, “surname”: “Stark”, …, “directory”: ????}

Learn more at Stormpath.com

Page 51: Design Beautiful REST + JSON APIs

Instance Reference (v1)

GET /accounts/x7y8z9

200 OK{ “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “givenName”: “Tony”, “surname”: “Stark”, …, “directory”: { “href”: “https://api.stormpath.com/v1/directories/g4h5i6” }}

Learn more at Stormpath.com

Page 52: Design Beautiful REST + JSON APIs

Collection Reference (v1)

GET /accounts/x7y8z9

200 OK{ “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “givenName”: “Tony”, “surname”: “Stark”, …, “groups”: { “href”: “https://api.stormpath.com/v1/accounts/x7y8z9/groups” }}

Learn more at Stormpath.com

Page 53: Design Beautiful REST + JSON APIs

Linking v2(recommended)

Learn more at Stormpath.com

Page 54: Design Beautiful REST + JSON APIs

Instance HREF (v2)

GET /accounts/x7y8z9

200 OK{ “meta”: { “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “mediaType”: “application/ion+json;version=2&schema=...” }, “givenName”: “Tony”, “surname”: “Stark”, …}

Learn more at Stormpath.com

Page 55: Design Beautiful REST + JSON APIs

Instance Reference (v2)

GET /accounts/x7y8z9

200 OK{ “meta”: { ... }, “givenName”: “Tony”, “surname”: “Stark”, …, “directory”: { “meta”: { “href”: “https://api.stormpath.com/v1/directories/g4h5i6” “mediaType”: “application/ion+json;version=2&schema=...” } }}

Learn more at Stormpath.com

Page 56: Design Beautiful REST + JSON APIs

Collection Reference (v2)

GET /accounts/x7y8z9

200 OK{ “meta”: { ... }, “givenName”: “Tony”, “surname”: “Stark”, …, “groups”: { “meta”: { “href”: “https://api.stormpath.com/v1/accounts/x7y8z9/groups”, “mediaType”: “application/ioncoll+json;version=2&schema=...” } }}

Learn more at Stormpath.com

Page 57: Design Beautiful REST + JSON APIs

Reference Expansion

(aka Entity Expansion, Link Expansion)

Learn more at Stormpath.com

Page 58: Design Beautiful REST + JSON APIs

Account and its Directory?

Learn more at Stormpath.com

Page 59: Design Beautiful REST + JSON APIs

GET /accounts/x7y8z9?expand=directory

200 OK{ “meta”: {...}, “givenName”: “Tony”, “surname”: “Stark”, …, “directory”: { “meta”: { ... }, “name”: “Avengers”, “description”: “Hollywood’s hope for more $”, “creationDate”: “2012-07-01T14:22:18.029Z”, … }}

Learn more at Stormpath.com

Page 60: Design Beautiful REST + JSON APIs

Partial Representations

Learn more at Stormpath.com

Page 61: Design Beautiful REST + JSON APIs

GET /accounts/x7y8z9?fields=givenName,surname,directory(name)

Learn more at Stormpath.com

Page 62: Design Beautiful REST + JSON APIs

Pagination

Learn more at Stormpath.com

Page 63: Design Beautiful REST + JSON APIs

Collection Resource supports query params:• Offset• Limit

…/applications?offset=50&limit=25

Learn more at Stormpath.com

Page 64: Design Beautiful REST + JSON APIs

GET /accounts/x7y8z9/groups

200 OK{ “meta”: { ... }, “offset”: 0, “limit”: 25, “first”: { “meta”:{“href”: “…/accounts/x7y8z9/groups?offset=0”}}, “previous”: null, “next”: { “meta”:{“href”: “…/accounts/x7y8z9/groups?offset=25”}}, “last”: { “meta”:{“href”: “…”}}, “items”: [ { “meta”: { “href”: “…”, ...} }, { “meta”: { “href”: “…”, ...} }, … ]}

Learn more at Stormpath.com

Page 65: Design Beautiful REST + JSON APIs

Many To Many

Learn more at Stormpath.com

Page 66: Design Beautiful REST + JSON APIs

Group to Account

• A group can have many accounts• An account can be in many groups• Each mapping is a resource:

GroupMembership

Learn more at Stormpath.com

Page 67: Design Beautiful REST + JSON APIs

GET /groupMemberships/23lk3j2j3

200 OK{ “meta”:{“href”: “…/groupMemberships/23lk3j2j3”}, “account”: { “meta”:{“href”: “…”} }, “group”: { “meta”{“href”: “…”} }, …}

Learn more at Stormpath.com

Page 68: Design Beautiful REST + JSON APIs

GET /accounts/x7y8z9

200 OK{ “meta”:{“href”: “…/accounts/x7y8z9”}, “givenName”: “Tony”, “surname”: “Stark”, …, “groups”: { “meta”:{“href”: “…/accounts/x7y8z9/groups”} }, “groupMemberships”: { “meta”:{“href”: “…/groupMemberships?accountId=x7y8z9”} }}

Learn more at Stormpath.com

Page 69: Design Beautiful REST + JSON APIs

Errors

Learn more at Stormpath.com

Page 70: Design Beautiful REST + JSON APIs

• As descriptive as possible• As much information as possible• Developers are your customers

Learn more at Stormpath.com

Page 71: Design Beautiful REST + JSON APIs

POST /directories

409 Conflict{ “status”: 409, “code”: 40924, “property”: “name”, “message”: “A Directory named ‘Avengers’ already exists.”, “developerMessage”: “A directory named ‘Avengers’ already exists. If you have a stale local cache, please expire it now.”, “moreInfo”: “https://www.stormpath.com/docs/api/errors/40924”} Learn more at Stormpath.com

Page 72: Design Beautiful REST + JSON APIs

Security

Learn more at Stormpath.com

Page 73: Design Beautiful REST + JSON APIs

Avoid sessions when possibleAuthenticate every request if necessaryStateless

Authorize based on resource content, NOT URL!

Use Existing Protocol:Oauth 1.0a, Oauth2, Basic over SSL only

Custom Authentication Scheme:Only if you provide client code / SDKOnly if you really, really know what you’re doing

Use API Keys instead of Username/Passwords

Learn more at Stormpath.com

Page 74: Design Beautiful REST + JSON APIs

401 vs 403

• 401 “Unauthorized” really means Unauthenticated

“You need valid credentials for me to respond to this request”

• 403 “Forbidden” really means Unauthorized

“I understood your credentials, but so sorry, you’re not allowed!”

Learn more at Stormpath.com

Page 75: Design Beautiful REST + JSON APIs

HTTP Authentication Schemes

• Server response to issue challenge:

WWW-Authenticate: <scheme name> realm=“Application Name”

• Client request to submit credentials:

Authorization: <scheme name> <data>

Learn more at Stormpath.com

Page 76: Design Beautiful REST + JSON APIs

API Keys

• Entropy• Password Reset• Independence• Speed• Limited Exposure• Traceability

Learn more at Stormpath.com

Page 77: Design Beautiful REST + JSON APIs

IDs

Learn more at Stormpath.com

Page 78: Design Beautiful REST + JSON APIs

• IDs should be opaque• Should be globally unique• Avoid sequential numbers

(contention, fusking)• Good candidates: UUIDs, ‘Url64’

Learn more at Stormpath.com

Page 79: Design Beautiful REST + JSON APIs

HTTP Method Overrides

Learn more at Stormpath.com

Page 80: Design Beautiful REST + JSON APIs

POST /accounts/x7y8z9?_method=DELETE

Learn more at Stormpath.com

Page 81: Design Beautiful REST + JSON APIs

Caching & Concurrency Control

Learn more at Stormpath.com

Page 82: Design Beautiful REST + JSON APIs

Server (initial response): ETag: "686897696a7c876b7e”

Client (later request):If-None-Match: "686897696a7c876b7e”

Server (later response):304 Not Modified

Learn more at Stormpath.com

Page 83: Design Beautiful REST + JSON APIs

Maintenance

Learn more at Stormpath.com

Page 84: Design Beautiful REST + JSON APIs

Use HTTP Redirects

Create abstraction layer / endpoints when migrating

Use well defined custom Media Types

Learn more at Stormpath.com

Page 85: Design Beautiful REST + JSON APIs

.com

• Free for developers• Eliminate months of development• Automatic security best practices

Sign Up Now: Stormpath.com


Related Documents