Upload
jason-harmon
View
151
Download
1
Tags:
Embed Size (px)
Citation preview
API DESIGN
FUNDAMENTALSJason Harmon
@jharmn
API DESIGN CONCERNS
• REST Constraints
• Developer Experience
• Scalability
• Sustainability
• Consistency
REST CONSTRAINTS
REVIEW• Client-server: separation of concerns
• Stateless: forget about sessions; everything for a request’s context must be
provided by client
• Cache: leveraging HTTP cache headers for scale and performance
• Interface/Uniform Contract: URI + HTTP + media type is all you need. Once you
define it, you can’t change it.
• Layered System: decoupled concerns, delegated responsibilities. Tiers
enhance distributed computing.
• Code on Demand: optional, and still not significantly adopted. The server
delivers code for the client to run.
RICHARDSON MATURITY
MODELhttp://martinfowler.com/articles/richardsonMaturityModel.html
PoX = Plain old XML
Richardson ended up disliking this chart; it should all be included
UNIFORM INTERFACE
CONCERNS• URL structure
• REST prescribes nothing: this is a great example of ‘architectural
style’, where we design by constraints, not overly specific
standards
• Resources
• Resources are not just database entities, more similar to an OO
object
• Leverages the HTTP verbs (GET, POST, PUT, DELETE, and
sometimes PATCH)
When resource modeling is done right, pretty URIs ensue
DEVELOPER
EXPERIENCEThink about being the API consumer
DEVELOPER EXPERIENCE• Always think in terms of what a client’s code will look like
• Client ease is more important than server difficulty
• Think in terms of behavior, not just data
• How many related calls need to be made to perform a
workflow?
• Will it be easy to derive all required fields?
• Is domain language understandable outside of your
domain?
DOCS ARE DX TOOIt doesn’t exist if you can’t read about it.
DOCUMENTATION IS DX
TOO• There is a school of thought around
“Documentation-Driven Design”
• http://nordicapis.com/using-templates-for-
documentation-driven-api-design/
• “Getting started” should be a big focus
• Working interactive samples make exploration
easy
DESIGN SCALABILITYResource modeling and the Goldilocks Principle
http://home.netcom.com/~swansont_2/goldilocks.jpg
TOO SMALL
HTTP CHATTINESS
• N+1 calls
• Serious performance barrier; network saturation and socket overhead
• HTTP/1.1 is not great at lots of calls (HTTP2 will help)
• Multipart media types can aid in batching requests
• Things to look for:
• Lists of data which require calling another URI to get enough details to
render that list in an app
• Fine-grained data broken into distinct URIs
TOO BIG
LONG-LIVED CONNECTIONS AND
BATCH/BULK
• Watch for large batch or bulk operations
• Error handling is tough
• System load can be risky
• HTTP can be unreliable on long-lived
connections
DESIGN SUSTAINABILITY
• Rationalize URIs and resource models that can
grow and mature
• Stay resource-focused so sub-resources can be
added later
• Try to keep resources first-class (i.e. one unique
identifier) so sub-resources can be added
without creating giant multi-identifier URIs
DESIGN SUSTAINABILITY
• Every URI that has RPC semantics is a dead
end
• It is impossible to add sub-context to an RPC
method
• New requirements tend to turn into new URIs
or versions
INTERFACE DESIGN“IMP”, packet-switching node used to interconnect
participant networks to the ARPANET from the late
1960s to 198
PARAMETERS• Header: platform concerns, use sparingly
• Don’t prefix with “X-“ https://tools.ietf.org/html/rfc6648
• Query: filter/search collections
• Request body:
• JSON: a little more complex, works anywhere
• form-encoded: pretty easy, limited in complex
resources
NAMING CONVENTIONS• URLs, Parameters, Request/Response
bodies
• Styles
• spine-case
• snake_case
• camelCase
NAMING
CONVENTIONSURLs/Parameters: pick one, stick with it (unlike
Monty Hall)
Request/response: use camelCase for JSON
VERSIONINGRule #1: Try not to
• Header-based
• URI is long-lived
• Developers can make mistakes
• No HTTP standard, usually proprietary
header
VERSIONING
• URL-based: “/v1”
• Used heavily in public APIs
• Hard to get wrong
• Low support cost
NAMESPACES• An organizational construct used to segregate the API
portfolio
• Example: /v1/shipping
• Often does not serve a purpose beyond name collision
• Be sure namespaces reflect customer perspective, not
system or internal organizational perspective
• Use caution in deep nesting of empty resource/sub-
namespaces
RESOURCE COLLECTIONS
• Plural noun indicates collection
• Example: /v1/shipping/invoices
• Must use unique resource identifier
• Example: /v1/shipping/invoices/INV-
3s29f213
RESOURCE IDENTIFIERS
• Sequential integers should be avoided
• Over-coupling to database sequences
• DOR (direct object reference) risks
• https://www.owasp.org/index.php/Top_10
_2007-A4
IDENTITY IN RESOURCE
IDS• Anti-pattern:
• /users/{userId}/{resourceName}
• Logs become identity exploit vectors
• Should only be used with data shared between users
• Header-based approach is better; not usually logged
• Authorization header is standard
SUB-RESOURCE
COLLECTIONS• When resource identifiers are ‘composite’, i.e. a
single identifier is inadequate
• Try to use unique identifiers when possible
• Avoid more than 2 identifiers; usability issues
• Example:
• /v1/shipping/invoices/{invoiceId}/items/{itemId}
FILTERS/QUERY
PARAMETERS• Paging
• offset/limit or page/pageNumber
• Time selection
• e.g. createdOn, updateAfter, activatedBefore
• Sorting
• sortBy/sortOrder
COLLECTIONS: HTTP
VERBS
POST GET PUT PATCH DELETE
/cars CreateRetrieve
list
Create
(pre known
ID)
or Update all
(risky)
Partial
update all
(risky)
Delete all
(Risky)
/cars/{
carId}N/A Retrieve Update full
Update
partialDelete
COLLECTIONS: HTTP
STATUS
POST GET PUT PATCH DELETE
/cars 201
200 (not
404 when
empty)
201 (create)
204 (update)204 204
/cars/{
carId}N/A 200 or 404 204 204 204
HTTP STATUS
• 200 OK
• 201 Created
• 204 No Content
• 400 Bad Request
• 404 Not Found
• 500 Server Error
COLLECTIONS: UPDATING
• /cars
• Complexity in updating multiple resources
• Should be treated atomically; no partial failure
• /cars/{carId}
• PUT updates full resource
• PATCH updates partial
UPDATING: PATCH
FORMATSJSON Patch
https://tools.ietf.org/html/rfc6902
PATCH FORMATSJSON Merge Patch
https://tools.ietf.org/html/rfc7396
CONTROLLERS• RPC-like, using POST to create or modify multiple resources
• Or if additional fields are required (e.g. ‘comment’, ‘reason’)
• Well described in RESTful Web Services Cookbook as
‘controller’
• http://www.amazon.com/RESTful-Web-Services-Cookbook-
Scalability/dp/0596801688
• Example: /v1/shipping/invoices/{invoiceId}/cancel
• Example: /v1/shipping/cancel-invoices
ACTIONS
• Typically a sub-resource
• Use a verb to indicate action
• Usually does not modify resource state
• Example:
• POST /v1/shipping/invoices/{invoiceId}/remind
• History/event sourcing should be considered
• POST /v1/shipping/invoices/{invoiceId}/reminders/{reminderId}
SEARCH
• Example: /v1/shipping/activity-search
• GET + query over POST for cache-ability
• POST not cacheable, complex scenarios
ISO STANDARDSInternational standards that work.
DATE/TIME/TIMEZONE
• RFC3339 https://www.ietf.org/rfc/rfc3339.txt
• Subset of ISO 8601
• Example: 2015-03-02T12:00:00+0500
• Accept timezone offsets, respond with UTC
DATE/TIME/TIMEZONE
• http://apiux.com/2013/03/20/5-laws-api-
dates-and-times/
• http://apiux.com/2013/09/11/api-timezones/
GLOBALIZATION
• ISO 639: Language Codes
• ISO 3166 alpha 2: Country Codes
• ISO 4217: Currency Codes
• http://apiux.com/2013/04/25/how-to-localize-
your-api/
PHONE NUMBERS• http://en.wikipedia.org/wiki/E.164
• Not ISO, ITU-T
• For example, to convert a US phone number (415 599 2671)
to E.164 format, one would need to add the ‘+’ prefix and the
country code (which is 1) in front of the number (+1 415 599
2671). In the UK and many other countries internationally,
local dialing requires the addition of a 0 in front of the
subscriber number. However, to use E.164 formatting, this 0
must be removed. A number such as 020 7183 8750 in the
UK would be formatted as +44 20 7183 8750.
HYPERMEDI
AHypermedia As The
Engine Of State
aka HATEOAS
FINITE STATE MACHINE
• Mapping your system’s state can be daunting
• Mapping per resource is an easier start
• Deep linking can create large link charts
TYPICAL FORMAT
• Array of links
• href: the target of the link
• rel: relationship to the resource
• IANA rels won’t do you much good
• verb: can be useful, not always used
EXAMPLE
BEST USES
• Related resources
• Paging: a must-have
• Abstract permissions
• Provide relevant actions to the resource’s state
• CRUD actions
• Controller/actions
FORMATS• Collection+JSON: http://amundsen.com/media-
types/collection/
• UBER: http://rawgit.com/uber-
hypermedia/specification/master/uber-hypermedia.html
• JSON API: http://jsonapi.org/
• HAL: http://stateless.co/hal_specification.html
• JSON-LD: http://json-ld.org/
• Siren:
https://github.com/kevinswiber/siren/blob/master/README.md
CUSTOM MEDIA TYPES
• Emerging field of design
• e.g. application/vnd.amundsen-uber+json not
application/json
• http://www.bizcoder.com/hypermedia-past-
present-and-future