diff --git a/contents/articles/pragmatic-api-design/index.md b/contents/articles/pragmatic-api-design/index.md index 73c3cdc..9a4f76a 100644 --- a/contents/articles/pragmatic-api-design/index.md +++ b/contents/articles/pragmatic-api-design/index.md @@ -1,229 +1,229 @@ ---- -title: Pragmatic API Design -author: geoff-doty -date: 2016-08-12 -template: article.jade ---- - -The API design *should* be organized around **REST** principles, however to maintain both user and developer sanity it should *also* be pragmatic, thus we call it **RESTful design**, as it may not conform to *all* the REST architecture design tenets. - -### Launch like a start-up, scale like an enterprise - -API's should have predictable, resource-oriented URLs and to use HTTP-based response codes to indicate API errors. Leveraging built-in HTTP features, like HTTP authentication and HTTP verbs, allows off-the-shelf HTTP clients to work out-of-the-box. - -> NOTE: `cross-origin` resource sharing only applies to browsers, and allows you to interact API's directly from a client-side web application - -By default, all API responses should return JSON, including errors - -## Authentication / Authorization - -### Basic Authentication - -- username:password should be key:password - -### Case for Bearer Tokens (JWT) - -Authorization based on [RFC 6750]() Bearer Tokens, a subset of the OAuth 2 framework. The bearer token is a [Javascript Web Token (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32) - -The Authentication / Authorization process first requires you have authenticated against the `trusts` API resource, then you use that Token to authorize future API requests. - -Example - - POST /tokens - { - "username": "", - "password": "" - } - -This will return the JWT security token that will be used for the remainder of the requests - - { - "token": "mF_9.B5f-4.1JqM" - } - -You authenticate to the API by providing one of your API keys in the request. You can manage your API keys from your account. You can have multiple API keys active at one time. - -Your API keys carry many privileges, so be sure to keep them secret! - -Authorization to the API occurs via a Javascript Web Token (JWT). Provide your API JWT token as the Authorization HTTP Header - - GET /resource HTTP/1.1 - Host: api.assistrxlabs.com - Authorization: Bearer mF_9.B5f-4.1JqM - -All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must provide the Authorization header for all requests. - -## Authentication - -You authenticate to the API by providing one of your API keys in the request. You can manage your API keys from your account. You can have multiple API keys active at one time. Your API keys carry many privileges, so be sure to keep them secret! - -Authentication to the API occurs via HTTP Basic Auth. Provide your API key as the basic auth username. You do not need to provide a password. - -All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must authenticate for all requests. - -### Endpoints - -To make the API as explorable as possible, accounts have test-mode API keys as well as live-mode API keys. These keys can be active at the same time. Data created with test-mode credentials will never hit the credit card networks and will never cost anyone money. - -Example Endpoints - -#### Development - - https://api.example.com/v1/ - -#### Production - - https://api.example.com/v1/ - -## RESTful Verbs (pragmatic) - -Core RESOURCES should map HTTP VERBS to CRUD operations - -- GET = read resource -- POST = create resource -- PUT = replace resource -- DELETE = delete resource (or mark as deleted -- never really delete) - -|Resource|GET|PUT|POST|DELETE| -|---|:---|:---|:--|:---|:---| -|.|read| update|create|remove| -|Collection /resources/|List the URIs and perhaps other details of the collection's members.|Replace the entire collection with another collection|Create a new entry in the collection. The new entry's URI is assigned automatically and is usually returned by the operation|Delete the entire collection| -|Element /resources/item|Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type|Replace the addressed member of the collection, or if it doesn't exist, create it|Not generally used. Treat the addressed member as a collection in its own right and create a new entry in it|Delete the addressed member of the collection| - -> NOTE: PATCH could update a resource, save for browser limitations - - -### URL Structure - -- first part of api should be version v1, v2 and not 1.2, or v1.5 ect… -- Additional URLs for - - api.example.com - - developers.example.com - - documents.example.com - -For Example - - https://api.example.com/v1/users - -> NOTE: as your developing an API, you can use '/v0' as your living API version - -### URI Resources - -- no verbs -- plural resource names -- /[api version]/[resource]/[identifier] - - /v1/cases/id/ - - /v1/jobs/id/ - -###### Resource Relationships (optional) - -- resource/id/resource - - /v1/jobs/id/applicants/ - - /v1/jobs/id/applicants/id - -### Actions - -- verbs not nouns - - /convert?from=EUR&to=CNY&amount=100 - - /search?q=??? - - /count - -### Search - - /search?q=item1+item2 - -this can be on a resource: - - /v1/docs/search?q=hash - -or on an item - - /v1/docs/1234/search?q=sample - -### Response Objects - -``` -{ - "data": [] - "pagination": {} -} -``` - -### Error Handling (extended) - -|Code| Description| -|--|---| -|1xx| Informational | -|2xx| Success | -|3xx| Redirection | -|4xx| Client Error| -|5xx| Server Error| - -### Common Codes - -| Code | Result | Summary | -|---|---|---| -| 200 | OK | Success| -| 400 | Bad Request | Often missing a required parameter| -| 401 | Unauthorized | No valid API key provided.| -| 402 | Request Failed | Parameters were valid but request failed. | -| 404 | Not Found | The requested item doesn't exist. -| 500 ||| -| 501 | Not Implemented | something went wrong on API's end. | - -Not all errors map cleanly onto HTTP response codes, but you should not throw out the HTTP responses codes, but rather extend. - -- `{code: , message:, link:}` - - code = extended http error ie 401-10 or 40110 - - message = error message - - link = url to documentation - -standard js error/exception object - - {name: "", message: ""} - - -#### Error Suppression - -- suppress error codes per request - - suppress\_response\_code = FALSE - -### Partial Responses - - ?fields=name,date,street - -### Pagination - -All top-level API resources have support for bulk fetches — "list" API methods. For instance you can list people, list places, and list things. These list API methods share a common structure. - -The API utilizes cursor-based pagination, using the parameter `offset`. Pass `offset` to dictate where in the list you would like to begin (see below). - -- limit -- offset - -Examples - - https://api.example.com/v0/users?offset=0&limit=10 - -### Return Data Formats - - ?format=json - -or - - .json - -### Variable Naming - -lowerCamelCase (ie follow javascript style for json api) - -### Reserved Words - -`count` as a reserved word - - /v1/docs/count - -### Fake Response Method - -- ?method=put -- ?method=delete +--- +title: Pragmatic API Design +author: geoff-doty +date: 2016-08-12 +template: article.jade +--- + +The API design *should* be organized around **REST** principles, however to maintain both user and developer sanity it should *also* be pragmatic, thus we call it **RESTful design**, as it may not conform to *all* the REST architecture design tenets. + +## Launch like a start-up, scale like an enterprise + +API's should have predictable, resource-oriented URLs and to use HTTP-based response codes to indicate API errors. Leveraging built-in HTTP features, like HTTP authentication and HTTP verbs, allows off-the-shelf HTTP clients to work out-of-the-box. + +> NOTE: `cross-origin` resource sharing only applies to browsers, and allows you to interact API's directly from a client-side web application + +By default, all API responses should return JSON, including errors + +## Authentication / Authorization + +### Basic Authentication + +- username:password should be key:password + +### Case for Bearer Tokens (JWT) + +Authorization based on [RFC 6750]() Bearer Tokens, a subset of the OAuth 2 framework. The bearer token is a [Javascript Web Token (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32) + +The Authentication / Authorization process first requires you have authenticated against the `trusts` API resource, then you use that Token to authorize future API requests. + +Example + + POST /tokens + { + "username": "", + "password": "" + } + +This will return the JWT security token that will be used for the remainder of the requests + + { + "token": "mF_9.B5f-4.1JqM" + } + +You authenticate to the API by providing one of your API keys in the request. You can manage your API keys from your account. You can have multiple API keys active at one time. + +Your API keys carry many privileges, so be sure to keep them secret! + +Authorization to the API occurs via a Javascript Web Token (JWT). Provide your API JWT token as the Authorization HTTP Header + + GET /resource HTTP/1.1 + Host: api.assistrxlabs.com + Authorization: Bearer mF_9.B5f-4.1JqM + +All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must provide the Authorization header for all requests. + +## Authentication + +You authenticate to the API by providing one of your API keys in the request. You can manage your API keys from your account. You can have multiple API keys active at one time. Your API keys carry many privileges, so be sure to keep them secret! + +Authentication to the API occurs via HTTP Basic Auth. Provide your API key as the basic auth username. You do not need to provide a password. + +All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must authenticate for all requests. + +### Endpoints + +To make the API as explorable as possible, accounts have test-mode API keys as well as live-mode API keys. These keys can be active at the same time. Data created with test-mode credentials will never hit the credit card networks and will never cost anyone money. + +Example Endpoints + +#### Development + + https://api.example.com/v1/ + +#### Production + + https://api.example.com/v1/ + +## RESTful Verbs (pragmatic) + +Core RESOURCES should map HTTP VERBS to CRUD operations + +- GET = read resource +- POST = create resource +- PUT = replace resource +- DELETE = delete resource (or mark as deleted -- never really delete) + +|Resource|GET|PUT|POST|DELETE| +|---|:---|:---|:--|:---|:---| +|.|read| update|create|remove| +|Collection /resources/|List the URIs and perhaps other details of the collection's members.|Replace the entire collection with another collection|Create a new entry in the collection. The new entry's URI is assigned automatically and is usually returned by the operation|Delete the entire collection| +|Element /resources/item|Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type|Replace the addressed member of the collection, or if it doesn't exist, create it|Not generally used. Treat the addressed member as a collection in its own right and create a new entry in it|Delete the addressed member of the collection| + +> NOTE: PATCH could update a resource, save for browser limitations + + +### URL Structure + +- first part of api should be version v1, v2 and not 1.2, or v1.5 ect… +- Additional URLs for + - api.example.com + - developers.example.com + - documents.example.com + +For Example + + https://api.example.com/v1/users + +> NOTE: as your developing an API, you can use '/v0' as your living API version + +### URI Resources + +- no verbs +- plural resource names +- /[api version]/[resource]/[identifier] + - /v1/cases/id/ + - /v1/jobs/id/ + +###### Resource Relationships (optional) + +- resource/id/resource + - /v1/jobs/id/applicants/ + - /v1/jobs/id/applicants/id + +### Actions + +- verbs not nouns + - /convert?from=EUR&to=CNY&amount=100 + - /search?q=??? + - /count + +### Search + + /search?q=item1+item2 + +this can be on a resource: + + /v1/docs/search?q=hash + +or on an item + + /v1/docs/1234/search?q=sample + +### Response Objects + +``` +{ + "data": [] + "pagination": {} +} +``` + +### Error Handling (extended) + +|Code| Description| +|--|---| +|1xx| Informational | +|2xx| Success | +|3xx| Redirection | +|4xx| Client Error| +|5xx| Server Error| + +### Common Codes + +| Code | Result | Summary | +|---|---|---| +| 200 | OK | Success| +| 400 | Bad Request | Often missing a required parameter| +| 401 | Unauthorized | No valid API key provided.| +| 402 | Request Failed | Parameters were valid but request failed. | +| 404 | Not Found | The requested item doesn't exist. +| 500 ||| +| 501 | Not Implemented | something went wrong on API's end. | + +Not all errors map cleanly onto HTTP response codes, but you should not throw out the HTTP responses codes, but rather extend. + +- `{code: , message:, link:}` + - code = extended http error ie 401-10 or 40110 + - message = error message + - link = url to documentation + +standard js error/exception object + + {name: "", message: ""} + + +#### Error Suppression + +- suppress error codes per request + - suppress\_response\_code = FALSE + +### Partial Responses + + ?fields=name,date,street + +### Pagination + +All top-level API resources have support for bulk fetches — "list" API methods. For instance you can list people, list places, and list things. These list API methods share a common structure. + +The API utilizes cursor-based pagination, using the parameter `offset`. Pass `offset` to dictate where in the list you would like to begin (see below). + +- limit +- offset + +Examples + + https://api.example.com/v0/users?offset=0&limit=10 + +### Return Data Formats + + ?format=json + +or + + .json + +### Variable Naming + +lowerCamelCase (ie follow javascript style for json api) + +### Reserved Words + +`count` as a reserved word + + /v1/docs/count + +### Fake Response Method + +- ?method=put +- ?method=delete