API DESIGN
FUNDAMENTALS
Jason 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 TOO
It 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 SCALABILITY
Resource 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
VERSIONING
Rule #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 Create
Retrieve
list
Create
(pre known
ID)
or Update all
(risky)
Partial
update all
(risky)
Delete all
(Risky)
/cars/{
carId}
N/A Retrieve Update full
Update
partial
Delete
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 FORMATS
JSON 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 STANDARDS
International 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
A
Hypermedia 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

Api Design

  • 1.
  • 2.
    API DESIGN CONCERNS •REST Constraints • Developer Experience • Scalability • Sustainability • Consistency
  • 3.
    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.
  • 4.
    RICHARDSON MATURITY MODELhttp://martinfowler.com/articles/richardsonMaturityModel.html PoX =Plain old XML Richardson ended up disliking this chart; it should all be included
  • 5.
    UNIFORM INTERFACE CONCERNS• URLstructure • 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
  • 6.
  • 7.
    DEVELOPER EXPERIENCE • Alwaysthink 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?
  • 8.
    DOCS ARE DXTOO It doesn’t exist if you can’t read about it.
  • 9.
    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
  • 10.
    DESIGN SCALABILITY Resource modelingand the Goldilocks Principle http://home.netcom.com/~swansont_2/goldilocks.jpg
  • 11.
    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
  • 12.
    TOO BIG LONG-LIVED CONNECTIONSAND 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
  • 13.
    DESIGN SUSTAINABILITY • RationalizeURIs 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
  • 14.
    DESIGN SUSTAINABILITY • EveryURI 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
  • 15.
    INTERFACE DESIGN “IMP”, packet-switchingnode used to interconnect participant networks to the ARPANET from the late 1960s to 198
  • 16.
    PARAMETERS • Header: platformconcerns, 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
  • 17.
    NAMING CONVENTIONS • URLs,Parameters, Request/Response bodies • Styles • spine-case • snake_case • camelCase
  • 18.
    NAMING CONVENTIONSURLs/Parameters: pick one,stick with it (unlike Monty Hall) Request/response: use camelCase for JSON
  • 19.
    VERSIONING Rule #1: Trynot to • Header-based • URI is long-lived • Developers can make mistakes • No HTTP standard, usually proprietary header
  • 20.
    VERSIONING • URL-based: “/v1” •Used heavily in public APIs • Hard to get wrong • Low support cost
  • 21.
    NAMESPACES • An organizationalconstruct 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
  • 22.
    RESOURCE COLLECTIONS • Pluralnoun indicates collection • Example: /v1/shipping/invoices • Must use unique resource identifier • Example: /v1/shipping/invoices/INV- 3s29f213
  • 23.
    RESOURCE IDENTIFIERS • Sequentialintegers should be avoided • Over-coupling to database sequences • DOR (direct object reference) risks • https://www.owasp.org/index.php/Top_10 _2007-A4
  • 24.
    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
  • 25.
    SUB-RESOURCE COLLECTIONS • When resourceidentifiers 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}
  • 26.
    FILTERS/QUERY PARAMETERS • Paging • offset/limitor page/pageNumber • Time selection • e.g. createdOn, updateAfter, activatedBefore • Sorting • sortBy/sortOrder
  • 27.
    COLLECTIONS: HTTP VERBS POST GETPUT PATCH DELETE /cars Create Retrieve list Create (pre known ID) or Update all (risky) Partial update all (risky) Delete all (Risky) /cars/{ carId} N/A Retrieve Update full Update partial Delete
  • 28.
    COLLECTIONS: HTTP STATUS POST GETPUT 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
  • 29.
    HTTP STATUS • 200OK • 201 Created • 204 No Content • 400 Bad Request • 404 Not Found • 500 Server Error
  • 30.
    COLLECTIONS: UPDATING • /cars •Complexity in updating multiple resources • Should be treated atomically; no partial failure • /cars/{carId} • PUT updates full resource • PATCH updates partial
  • 31.
  • 32.
    PATCH FORMATS JSON MergePatch https://tools.ietf.org/html/rfc7396
  • 33.
    CONTROLLERS • RPC-like, usingPOST 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
  • 34.
    ACTIONS • Typically asub-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}
  • 35.
    SEARCH • Example: /v1/shipping/activity-search •GET + query over POST for cache-ability • POST not cacheable, complex scenarios
  • 36.
  • 37.
    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
  • 38.
  • 39.
    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/
  • 40.
    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.
  • 41.
  • 42.
    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
  • 43.
    TYPICAL FORMAT • Arrayof 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
  • 44.
  • 45.
    BEST USES • Relatedresources • Paging: a must-have • Abstract permissions • Provide relevant actions to the resource’s state • CRUD actions • Controller/actions
  • 46.
    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
  • 47.
    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