Skip to content

Instantly share code, notes, and snippets.

@gomaglev
Last active January 27, 2021 08:54
Show Gist options
  • Save gomaglev/ac99523d61c92ca2ad1c68cbbf3bca92 to your computer and use it in GitHub Desktop.
Save gomaglev/ac99523d61c92ca2ad1c68cbbf3bca92 to your computer and use it in GitHub Desktop.
Rest API Best Practice

Rest API

REpresentational State Transfer API.

1. REST operations to database operations

POST       - CREATE/INSERT
GET        — SELECT
PUT/PATCH  - UPDATE
DELETE     - DELETE/TRUNCATE/DROP

2. URL design

Since Rest API is stateless, resource based architecture, the first thing to be considered is resource access control. There are two ways to control the resource.

Authentication

It's a system level protection of resources using Password, One-time pin, Authentication apps or Biometrics. Famous authentication providers include Google, Auth0, AWS, etc.

Authorization

Authorization is the process of giving the user permission to access specific resources. Role based access control is widely used to do authorization. Nested resource design must be considered from the very beginning for easier authorization in REST API. It will be helpful when using service mesh to do RBAC.

Good examples

GET v1/companies/{company_id}/applications/{application_id}/users/{user_id}/resources?pagination=true&page=1&page_size=100
GET v1/companies/{company_id}/applications/{application_id}/users/{user_id}/resources/{resource_id}
POST v1/companies/{company_id}/applications/{application_id}/users/{user_id}/resources
PUT v1/companies/{company_id}/applications/{application_id}/users/{user_id}/resources/{resource_id}

Bad examples

GET /resources?pagination=true&page=1&page_size=100
GET /resources/{resource_id}
POST /resources
PUT /resources/{resource_id}

3. Fields & Sort

Since REST APIs are stateless. To achieve better performance and reduce server cost, only fields used by client side should be responed to reduce the payload size. Passing field list by URL is not a good idea because it will cause URL too long and not easy to maintenance. A good idea is create a pre-defined Hashmap and load it into memory when service started. For example:

map[string][]string
key: "USER_LIST_FIELDS"
value: []string {
    "first_name",
    "last_name",
    "role_id",
    ...
}

Then pass a selection key as a query parameter to retrieve pre-defined fields only. Order by fields can also do same thing.

GET /companies/{company_id}/applications/{application_id}/users?selection=USER_LIST_FIELDS

4. Pagination

See Pagination

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