needs to be h2 for preview seperation

This commit is contained in:
Geoff Doty 2018-05-03 00:36:43 -04:00
parent 0325f32e5c
commit bb436b5392
1 changed files with 229 additions and 229 deletions

View File

@ -1,229 +1,229 @@
--- ---
title: Pragmatic API Design title: Pragmatic API Design
author: geoff-doty author: geoff-doty
date: 2016-08-12 date: 2016-08-12
template: article.jade 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. 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 ## 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. 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 > 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 By default, all API responses should return JSON, including errors
## Authentication / Authorization ## Authentication / Authorization
### Basic Authentication ### Basic Authentication
- username:password should be key:password - username:password should be key:password
### Case for Bearer Tokens (JWT) ### 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) 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. 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 Example
POST /tokens POST /tokens
{ {
"username": "<your username>", "username": "<your username>",
"password": "<your password>" "password": "<your password>"
} }
This will return the JWT security token that will be used for the remainder of the requests This will return the JWT security token that will be used for the remainder of the requests
{ {
"token": "mF_9.B5f-4.1JqM" "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. 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! 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 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 GET /resource HTTP/1.1
Host: api.assistrxlabs.com Host: api.assistrxlabs.com
Authorization: Bearer mF_9.B5f-4.1JqM 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. 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 ## 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! 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. 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. All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must authenticate for all requests.
### Endpoints ### 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. 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 Example Endpoints
#### Development #### Development
https://api.example.com/v1/ https://api.example.com/v1/
#### Production #### Production
https://api.example.com/v1/ https://api.example.com/v1/
## RESTful Verbs (pragmatic) ## RESTful Verbs (pragmatic)
Core RESOURCES should map HTTP VERBS to CRUD operations Core RESOURCES should map HTTP VERBS to CRUD operations
- GET = read resource - GET = read resource
- POST = create resource - POST = create resource
- PUT = replace resource - PUT = replace resource
- DELETE = delete resource (or mark as deleted -- never really delete) - DELETE = delete resource (or mark as deleted -- never really delete)
|Resource|GET|PUT|POST|DELETE| |Resource|GET|PUT|POST|DELETE|
|---|:---|:---|:--|:---|:---| |---|:---|:---|:--|:---|:---|
|.|read| update|create|remove| |.|read| update|create|remove|
|Collection <code>/resources/</code>|<b>List</b> the URIs and perhaps other details of the collection's members.|<b>Replace</b> the entire collection with another collection|<b>Create</b> a new entry in the collection. The new entry's URI is assigned automatically and is usually returned by the operation|<b>Delete</b> the entire collection| |Collection <code>/resources/</code>|<b>List</b> the URIs and perhaps other details of the collection's members.|<b>Replace</b> the entire collection with another collection|<b>Create</b> a new entry in the collection. The new entry's URI is assigned automatically and is usually returned by the operation|<b>Delete</b> the entire collection|
|Element <code>/resources/item</code>|<b>Retrieve</b> a representation of the addressed member of the collection, expressed in an appropriate Internet media type|<b>Replace</b> the addressed member of the collection, or if it doesn't exist, <b>create</b> it|Not generally used. Treat the addressed member as a collection in its own right and <b>create</b> a new entry in it|<b>Delete</b> the addressed member of the collection| |Element <code>/resources/item</code>|<b>Retrieve</b> a representation of the addressed member of the collection, expressed in an appropriate Internet media type|<b>Replace</b> the addressed member of the collection, or if it doesn't exist, <b>create</b> it|Not generally used. Treat the addressed member as a collection in its own right and <b>create</b> a new entry in it|<b>Delete</b> the addressed member of the collection|
> NOTE: PATCH could update a resource, save for browser limitations > NOTE: PATCH could update a resource, save for browser limitations
### URL Structure ### URL Structure
- first part of api should be version v1, v2 and not 1.2, or v1.5 ect… - first part of api should be version v1, v2 and not 1.2, or v1.5 ect…
- Additional URLs for - Additional URLs for
- api.example.com - api.example.com
- developers.example.com - developers.example.com
- documents.example.com - documents.example.com
For Example For Example
https://api.example.com/v1/users https://api.example.com/v1/users
> NOTE: as your developing an API, you can use '/v0' as your living API version > NOTE: as your developing an API, you can use '/v0' as your living API version
### URI Resources ### URI Resources
- no verbs - no verbs
- plural resource names - plural resource names
- /[api version]/[resource]/[identifier] - /[api version]/[resource]/[identifier]
- /v1/cases/id/ - /v1/cases/id/
- /v1/jobs/id/ - /v1/jobs/id/
###### Resource Relationships (optional) ###### Resource Relationships (optional)
- resource/id/resource - resource/id/resource
- /v1/jobs/id/applicants/ - /v1/jobs/id/applicants/
- /v1/jobs/id/applicants/id - /v1/jobs/id/applicants/id
### Actions ### Actions
- verbs not nouns - verbs not nouns
- /convert?from=EUR&to=CNY&amount=100 - /convert?from=EUR&to=CNY&amount=100
- /search?q=??? - /search?q=???
- /count - /count
### Search ### Search
/search?q=item1+item2 /search?q=item1+item2
this can be on a resource: this can be on a resource:
/v1/docs/search?q=hash /v1/docs/search?q=hash
or on an item or on an item
/v1/docs/1234/search?q=sample /v1/docs/1234/search?q=sample
### Response Objects ### Response Objects
``` ```
{ {
"data": [] "data": []
"pagination": {} "pagination": {}
} }
``` ```
### Error Handling (extended) ### Error Handling (extended)
|Code| Description| |Code| Description|
|--|---| |--|---|
|1xx| Informational | |1xx| Informational |
|2xx| Success | |2xx| Success |
|3xx| Redirection | |3xx| Redirection |
|4xx| Client Error| |4xx| Client Error|
|5xx| Server Error| |5xx| Server Error|
### Common Codes ### Common Codes
| Code | Result | Summary | | Code | Result | Summary |
|---|---|---| |---|---|---|
| 200 | OK | Success| | 200 | OK | Success|
| 400 | Bad Request | Often missing a required parameter| | 400 | Bad Request | Often missing a required parameter|
| 401 | Unauthorized | No valid API key provided.| | 401 | Unauthorized | No valid API key provided.|
| 402 | Request Failed | Parameters were valid but request failed. | | 402 | Request Failed | Parameters were valid but request failed. |
| 404 | Not Found | The requested item doesn't exist. | 404 | Not Found | The requested item doesn't exist.
| 500 ||| | 500 |||
| 501 | Not Implemented | something went wrong on API's end. | | 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. 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: , message:, link:}`
- code = extended http error ie 401-10 or 40110 - code = extended http error ie 401-10 or 40110
- message = error message - message = error message
- link = url to documentation - link = url to documentation
standard js error/exception object standard js error/exception object
{name: "", message: ""} {name: "", message: ""}
#### Error Suppression #### Error Suppression
- suppress error codes per request - suppress error codes per request
- suppress\_response\_code = FALSE - suppress\_response\_code = FALSE
### Partial Responses ### Partial Responses
?fields=name,date,street ?fields=name,date,street
### Pagination ### 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. 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). 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 - limit
- offset - offset
Examples Examples
https://api.example.com/v0/users?offset=0&limit=10 https://api.example.com/v0/users?offset=0&limit=10
### Return Data Formats ### Return Data Formats
?format=json ?format=json
or or
.json .json
### Variable Naming ### Variable Naming
lowerCamelCase (ie follow javascript style for json api) lowerCamelCase (ie follow javascript style for json api)
### Reserved Words ### Reserved Words
`count` as a reserved word `count` as a reserved word
/v1/docs/count /v1/docs/count
### Fake Response Method ### Fake Response Method
- ?method=put - ?method=put
- ?method=delete - ?method=delete