Top Banner
Beautiful REST + JSON APIs Les Hazlewood @lhazlewood CTO, Stormpath stormpath.com
85

Design Beautiful REST + JSON APIs

Sep 08, 2014

Download

Technology

Stormpath

Les Hazlewood, Stormpath co-founder and CTO and the Apache Shiro PMC Chair demonstrates how to design a beautiful REST + JSON API. Includes the principles of RESTful design, how REST differs from XML, tips for increasing adoption of your API, and security concerns.

Presentation video: https://www.youtube.com/watch?v=5WXYw4J4QOU
More info: http://www.stormpath.com/blog/designing-rest-json-apis
Further reading: http://www.stormpath.com/blog

Stormpath is a user management and authentication service for developers. By offloading user management and authentication to Stormpath, developers can bring applications to market faster, reduce development costs, and protect their users. Easy and secure, the flexible cloud service can manage millions of users with a scalable pricing model.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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