Skip to content

kudobuzz/api-standards

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 

Repository files navigation

Kudobuzz Api Standards

Guidelines

This document provides guidelines and examples for Kudobuzz APIs, encouraging consistency, maintainability, and best practices across services. Our APIs aim to balance a truly RESTful API interface with a positive developer experience (DX).

This document borrows heavily from:

RESTful URLs

General guidelines for RESTful URLs

  • A URL identifies a resource.
  • URLs should include nouns, not verbs.
  • Use plural nouns only for consistency (no singular nouns).
  • Use HTTP verbs (GET, POST, PUT, DELETE) to operate on the collections and elements.
  • You shouldn’t need to go deeper than resource/identifier/resource.
  • Put the version number at the base of your URL, for example https://api.kudobuzz.com/v1/path/to/resource
  • URL v. header:
    • If it changes the logic you write to handle the response, put it in the URL.
    • If it doesn’t change the logic for each response, like OAuth info, put it in the header.
  • Specify optional fields in a comma separated list.
  • Formats should be in the form of api/v2/resource/{id}
  • Design resource representations. Don’t simply represent database tables.
  • Support field projections on resources. Allow clients to reduce the number of fields that come back in the response.
  • For non-resource requests, url should identify the action being taken. E.g. if the endpoint converts 100 euros to chinese yen, is should look like /convert?from=EURO&to=YEN&amount=100
  • Make it clear in your API documentation that the "non-resource" scenarios are different. You can do this by simply separating out a section of your documentation that makes it clear that you use verbs in cases like this.

Good URL examples

Bad URL examples

HTTP Verbs

HTTP verbs, or methods, should be used in compliance with their definitions under the HTTP/1.1 standard. The action taken on the representation will be contextual to the media type being worked on and its current state. Here's an example of how HTTP verbs map to create, read, update, delete operations in a particular context:

HTTP METHOD POST GET PUT DELETE
CRUD OP CREATE READ UPDATE DELETE
/dogs Create new dogs List dogs Bulk update Delete all dogs
/dogs/1234 Error Show Bo If exists, update Bo; If not, error Delete Bo

(Example from Web API Design, by Brian Mulloy, Apigee.)

Responses

  • No values in keys

Good examples

No values in keys:

"tags": [
  {"id": "125", "name": "Environment"},
  {"id": "834", "name": "Water Quality"}
],

Bad examples

Values in keys:

"tags": [
  {"125": "Environment"},
  {"834": "Water Quality"}
],

Http Status Codes

There are currently over 70 status codes, it is difficult for developers to memorize all of these codes. Use only a small subset of common status codes.

Status Code Description
200 OK The request was successfully processed
201 Created The request has been fulfilled and the new resource has been created
400 Bad Request The request was not understood by server due bad syntax, request contains invalid and missing request details.
404 Not Found The resource was not found
401 UnAuthorised The request is missing the necessary authentication details
403 Forbidden The request credentials does not have the permission to perform that action on the resource
422 UnProcessable Entity The request body is well formed but contains semantical errors. The error response body will contain more details
429 Too Many Requests The request was not accepted because the application has exceeded the rate limit.

Error handling

Error responses can include message for the developer,an optional internal error code (corresponding to some specific internally determined ID), details for validation errors. For example:

{
  "error": {
     "message" : "Verbose, plain language description of the problem. Provide developers
                  suggestions about how to solve their problems here",required
      "code" : "444444", // this is not the same statusCodes, optional
      "details": [{param, messeage, value}] // Validation Error details, optional
  }
}

Versions

  • Never release an Public API Gateway without a version number.
  • Versions should be integers, not decimal numbers, prefixed with ‘v’. For example:
    • Good: v1, v2, v3
    • Bad: v-1.1, v1.2, 1.3
  • Maintain APIs at least one version back.

Record limits

Information about record limits and total available count should also be included in the response. Example:

{
    "metadata": {
      "count": 227       
    },
    "data": []
}

Request & Response Examples

API Resources

GET /magazines

Example: https://example.gov/api/v1/magazines

Response body:

{
    "metadata": {
       "count": 123
    },
    "data": [
        {
            "id": "1234",
            "type": "magazine",
            "title": "Public Water Systems",
            "tags": [
                {"id": "125", "name": "Environment"},
                {"id": "834", "name": "Water Quality"}
            ],
            "created": "1231621302"
        },
        {
            "id": 2351,
            "type": "magazine",
            "title": "Public Schools",
            "tags": [
                {"id": "125", "name": "Elementary"},
                {"id": "834", "name": "Charter Schools"}
            ],
            "created": "126251302"
        }
        {
            "id": 2351,
            "type": "magazine",
            "title": "Public Schools",
            "tags": [
                {"id": "125", "name": "Pre-school"},
            ],
            "created": "126251302"
        }
    ]
}

GET /magazines?tag=some-tag-name

Example 1: https://example.gov/api/v1/magazines?type=magazine

Returns response with an array with multiple objects

Response body:

{
    "metadata": {
       "count": 123
    },
    "data": [
        {
            "id": "1234",
            "type": "magazine",
            "title": "Public Water Systems",
            "tags": [
                {"id": "125", "name": "Environment"},
                {"id": "834", "name": "Water Quality"}
            ],
            "created": "1231621302"
        },
        {
            "id": 2351,
            "type": "magazine",
            "title": "Public Schools",
            "tags": [
                {"id": "125", "name": "Elementary"},
                {"id": "834", "name": "Charter Schools"}
            ],
            "created": "126251302"
        }
        {
            "id": 2351,
            "type": "magazine",
            "title": "Public Schools",
            "tags": [
                {"id": "125", "name": "Pre-school"},
            ],
            "created": "126251302"
        }
    ]
}

Example 2: https://example.gov/api/v1/magazines?special_code=code-1234

Returns response with a single object

{
  "data": {
    "id": "1234",
    "type": "magazine",
    "title": "Public Water Systems",
    "tags": [
        {"id": "125", "name": "Environment"},
        {"id": "834", "name": "Water Quality"}
    ],
    "created_at": "1231621302",
    "updated_at": "12321621302"
 }
}

Response body

GET /magazines/[id]

Example: http:/api.kudouzz.com/v1/api/magazines/[id]

Response body:

{
  "data": {
    "id": "1234",
    "type": "magazine",
    "title": "Public Water Systems",
    "tags": [
        {"id": "125", "name": "Environment"},
        {"id": "834", "name": "Water Quality"}
    ],
    "created_at": "1231621302",
    "updated_at": "12321621302"
 }
}

POST /magazines/bulk

Example: Create – POST https://api.kudobuzz.com/v1/magazines/bulk

Request body:

[
  {
    "title": "Water Quality",
    "year": "2012",
    "month": "August",
    "description": "Your one-stop information source on how to preserve water"
  },
  {
    "title": "Global warming"
    "year": "2020",
    "month": "July",
    "description": "Tips for slowing down the inevitable"
  }
]

Response body:

{
  "data": [
    {
      "id": "1235",
      "title": "Water Quality",
      "description": "Your one-stop information source on how to preserve water",
      "year": "2012",
      "month": "August",
      "created_at": "1231621302",
      "updated_at": "12321621302"
   },
    {
      "id": "1236",
      "title": "Global warming"
      "description": "Tips for slowing down the inevitable",
      "year": "2020",
      "month": "July",
      "created_at": "1231621302",
      "updated_at": "12321621302"
    }
  ]
}

POST /magazines/[id]/articles

Example: Create – POST https://api.kudobuzz.com/v1/magazines/[id]/articles

Request body:

{ 
"data": {
   "title": "Raising Revenue",
   "author_first_name": "Jane",
   "author_last_name": "Smith",
   "author_email": "[email protected]",
   "year": "2012",
   "month": "August",
   "day": "18",
   "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eget ante ut augue scelerisque ornare. Aliquam tempus rhoncus quam vel luctus. Sed scelerisque fermentum fringilla. Suspendisse tincidunt nisl a metus feugiat vitae vestibulum enim vulputate. Quisque vehicula dictum elit, vitae cursus libero auctor sed. Vestibulum fermentum elementum nunc. Proin aliquam erat in turpis vehicula sit amet tristique lorem blandit. Nam augue est, bibendum et ultrices non, interdum in est. Quisque gravida orci lobortis... "
   }
}

Rate Limiting

Ensure that your apis' are protected against sudden increase in request. Use the following headers to notify consumers if they exceeded the number request in a specif interval.

X-Rate-Limit-Limit - the number of request allowed in a given interval

X-Rate-Limit-Remaining- the number of request remaining

X-Rate-Limit-Reset- the next time for reset

Idempotent

Ensure that your GET, PUT, and DELETE operations are all idempotent. There should be no adverse side affects from operations.

Security

Use OAuth2 to secure your API.

  • Use a Bearer token for authentication.
  • Require HTTPS / TLS / SSL to access your APIs. OAuth2 Bearer tokens demand it. Unencrypted communication over HTTP allows for simple eavesdroppping and impersonation.

Docs

You write APIs so others can use them, benefit from them. Providing an API documentation for your REST APIs are crucial. Use Api Blueprint

Examples

Github

Twilio

Stripe

DigitalOcean