Skip to content

Instantly share code, notes, and snippets.

@iuridiniz
Last active November 24, 2022 02:03
Show Gist options
  • Save iuridiniz/9a1b4e78d041eb599cd6568a6db66323 to your computer and use it in GitHub Desktop.
Save iuridiniz/9a1b4e78d041eb599cd6568a6db66323 to your computer and use it in GitHub Desktop.
API GUIDELINES

BASED on:

General guide lines

Do not use verbs

Example:

  • If you want to pause someone, do not use POST /api/v1/pause?user=<user>, use: PATCH /api/v1/users/<user> and in the body use: {status: "paused" }

HTTP Status Codes

  • 200 OK: This single resource exists, it is returned. Or your request is valid, a collection is returned (could be an empty collection).
  • 201 Created: The object was created.
  • 204 No Content: The request is valid, it was processed and it returned nothing.
  • 400 Bad Request: The request body is invalid (Only for POST, PUT, PATCH, DELETE). So you can't return 400 from GET (There's no body)
  • 401 Unauthorized: The request is missing authentication.
  • 403 Forbidden: The request is authenticated but it is not allowed to perform this operation. Misisng Permission.
  • 404 Not Found: The single resource does not exists

Requests

  • Input content-type default: application/json
  • Input content-type alternative: application/x-www-form-urlencoded
  • Input could be a single or a collection of objects

Responses

  • Output content-type: application/json

Sample:

{
    status: "<same status code of http>",
    message: "<same message of http code>",
    data: "<the actual response of API cal if a 200 OK, not defined if an error>"
}

HTTP Commands basics

Plural

POST /api/v1/(resource in plural)

Create/upload a new (resource)

  • Input: only a single object

  • Must return a 201 Created or a 200 OK, If 200 OK, the object must be returned.

GET /api/v1/(resource in plural)

Retrieve a collection of a stored resource

  • If no query string: Get all resources
  • Returned data must be a list, even if no resourses or only a single resource
  • Implicit limit: 50

DELETE /api/v1/(resource in plural)

Delete all stored resources

  • MUST BE AVOIDED

PUT /api/v1/(resource in plural)

Bulk create or replace of resources

  • MUST BE AVOIDED

PATCH /api/v1/(resource in plural)

Bulk change/partial update of resources

  • MUST BE AVOIDED

Singular

POST /api/v1/(resource in plural)/{id}

Avoid using POST on single resource

GET /api/v1/(resource in plural)/{id}

Retrieve a single stored resource

DELETE /api/v1/(resource in plural)/{id}

Delete a single stored resources

  • MUST BE AVOIDED or use a soft delete

PUT /api/v1/(resource in plural)/{id}

Replace a resource

PATCH /api/v1/(resource in plural)/{id}

Partial update of resources

  • Content-type default: application/json
  • Content-type alternative: application/json-patch+json

GET filter, modifications

  • _sort=<field>: order by <field>, an optional '-' (minus) could be used to indicate reverse order.
  • _offset=<m>: skip first <m> elements.
  • _limit=<n>: only first <n> elements, if _offset=<m> is provided, the next <n> elements after first <m> elements will be returned. There is no guarantee that <n> elements will be returned, they can be less, they can be more.
  • _fields=<f1,f2,..>: output only fields <f1,f2,..>
  • <field>=<value>: ouput only resources with field <field> equal to value. Can be multiple (logical AND).
  • <field>=!<value>: ouput only resources with field <field> not equal to value. Can be multiple (logical AND).

Examples:

GET /api/v1/users?_sort=-id&_limit=2&_fields=name

  • This will only output the name of max 2 users, order by their id in descending order.

GET /api/v1/messages?_limit=50&status=unread

  • This will only output the a max of 50 messages where their status is 'unread'

You do a OR by issuing two requests. If you want atomicity, DO a special POST with Content-Type: multipart/mixed; to a BATCH endpoint

@iuridiniz
Copy link
Author

Example batch request from https://developers.google.com/gmail/api/guides/batch#example

POST /batch/farm/v1 HTTP/1.1
Authorization: Bearer your_auth_token
Host: www.googleapis.com
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item1:[email protected]>

GET /farm/v1/animals/pony

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item2:[email protected]>

PUT /farm/v1/animals/sheep
Content-Type: application/json
Content-Length: part_content_length
If-Match: "etag/sheep"

{
  "animalName": "sheep",
  "animalAge": "5"
  "peltColor": "green",
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item3:[email protected]>

GET /farm/v1/animals
If-None-Match: "etag/animals"

--batch_foobarbaz--

Example batch response:

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:[email protected]>

HTTP/1.1 200 OK
Content-Type application/json
Content-Length: response_part_1_content_length
ETag: "etag/pony"

{
  "kind": "farm#animal",
  "etag": "etag/pony",
  "selfLink": "/farm/v1/animals/pony",
  "animalName": "pony",
  "animalAge": 34,
  "peltColor": "white"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:[email protected]>

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: response_part_2_content_length
ETag: "etag/sheep"

{
  "kind": "farm#animal",
  "etag": "etag/sheep",
  "selfLink": "/farm/v1/animals/sheep",
  "animalName": "sheep",
  "animalAge": 5,
  "peltColor": "green"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item3:[email protected]>

HTTP/1.1 304 Not Modified
ETag: "etag/animals"

--batch_foobarbaz--

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment