REST API Design Guide

Common Guideline

References

Best Practices

Common Concepts

Date, Time, Interval, Duration

State or Status

Domain Modeling

Naming Convention

Element Convention Remarks
Resource Collection Name lowerCamelCase  

Common Abbreviation

Abbreviated Name Full Name Remarks
id identifier  
spec specification  
stats statistics  
req request  
resp response  

Custom Request Header

Header Field Description Value Space Default Sample Remarks
X-User-Locale          
X-User-Timezone          
X-Client-Can-Build-Message          
X-Auth-Token a token value for API access which was gained from authentication process     5aded866-9248-4058-879d-9266bdc4cd02  

Custom Response Header

Header Field Description Value Space Default Sample Remarks
X-Rate-Limit-Limit the rate limit ceiling for that given endpoint positive integer      
X-Rate-Limit-Remaining the number of requests left for the current time window non-negative integer      
X-Rate-Limit-Reset the remaining window before the rate limit resets, in UTC epoch seconds non-negative integer      
X-Page-Ended   boolean true    

Response Code

Successful Response

Code Status Description Example
200 OK The request has succeeded.  
201 Created The request has been fulfilled and resulted in a new resource being created.  
202 Accepted The request has been accepted for processing, but the processing has not been completed.  
204 No Content The server has fulfilled the request but does not need to return an entity-body, and might want to return updated  
metainformation.      

Error Response

Cause Code Status Processed By Remarks
When the client accesses undefined API(URL) 404 Not Found Framework  
When the request is not ‘application/json’ type 415 Unsupported Media Type Framework What if the API doesn’t need request body ?
When the client is not properly authenticated 401 Unauthorized Framework  
When the client accesses the API that is not permitted to him/her 403 Forbidden Framework  
When the client send JSON data that can’t be parsed 400 Bad Request Framework  
When the request doesn’t contain required parameters 400 Bad Request Framework  
When the request contains required parameters but has an invalid value among them 400 Bad Request Controller  
When the resource (User, Product, Order, Point, …) to find, update or remove doesn’t exist 404 Not Found Controller  
When the resource to add already exists        
When the server causes errors processing the request 500 Internal Server Error Controller network error, data access error
Consideration

Pattern, Best Practice

Common Path Word And Query Parameter

Word Description Sample
/count    
/refresh    
/belong-to/{userId}    
/recent    
/last    
?pageSize={size)&pageNo={no}    
?sort={sortBy}    

Pagination

Base API

Title Method Path Req. Body Resp. Body Remakrs
Get current version of messages GET /messages/version      
List all defined messages or message templates GET /messages      
List all available locales GET /locales      
List all available timezones GET /timezones      
List developers of this application both current and past GET /crews      
List current developers of this application GET /crews/current      
List past developers who is not working for this appl any more but .. GET /crews/past      
List release notes GET /releasenotes      

Complex Resources Hierarchy

GitHub API Style
Method Path Title Remarks
GET /users/:username/repos List repositories for a user  
GET /repos/:owner/:repo/releases List releases for a repository  

Standard

HTTP Method Summary

Method RFC Request Has Body Response Has Body Safe Idempotent Cacheable
GET RFC 7231 No Yes Yes Yes Yes
HEAD RFC 7231 No No Yes Yes Yes
POST RFC 7231 Yes Yes No No Yes
PUT RFC 7231 Yes Yes No Yes No
DELETE RFC 7231 No Yes No Yes No
CONNECT RFC 7231 Yes Yes No No No
OPTIONS RFC 7231 Optional Yes Yes Yes No
TRACE RFC 7231 No Yes Yes Yes No
PATCH RFC 5789 Yes Yes No No Yes

Examples

Well-Known Examples

API Title Link Remarks
GET /users/self/ Get information about the owner of access token. Instagram User Endpoints  

Service Program Example

Title Method Path Privilege Body Return Remarks
List service program entry posts GET service/entryPosts user   EntryPost[]  
Add a new service program entry post POST service/entryPosts user EntryPost   the owner of the post = current session, No one can add other user’s post
Add a new ‘Like’ for a entry post POST service/entryPosts/{postId}/likes user     the user who add a like = current session
Cancel a ‘Like’ for a entry post DELETE service/entryPost/{postId}/likes user     the user who cancel a like = current session
List service programs GET service/programs user   Program[]  
List open service programs GET service/programs/open user   Program[]  
List service programs in process GET service/programs/started user   Program[]  
List service programs reivewed GET service/programs/completed user   Program[]  
Find a service program GET service/programs/{programId} user   Program  
Find a open service program GET service/programs/open/{programId} user   Program  
List service programs coordinated by a coordinator GET service/programs/coordinatedBy/{coordinatorId} user      
Get a coordinator of the service program GET service/programs/{programId}/coordinator user      
Update the review of the service program PUT service/programs/{programId}/ user Review    
List my service program entries GET service/programs/-/entries/belongToMe user   Entry[] the owner of the program entry = current session
Find a single my service program entry GET service/programs/-/entries/{entryId} user   Entry the owner of the program entry == current session
Cancel a certain my service program entry DELETE service/programs/-/entries/{entryId} user     the owner of the program entry == current session
List program entries of a certain user GET service/programs/-/entries/belongTo/{userId} admin   Entry[]  
Find a program entry GEt service/programs/-/entries/{entryId} admin   Entry  

Block Explorer Example

Title Method Path Privilege Body Return Remarks
Find a block of specified no GET blocks/{blockNo}     Block  
Find recent blocks GET blocks/recent     BlockHeader[]  
Find initial blocks GET blocks/inital     BlockHeader[]  
Find blocks within the specified interval GET blocks/within?from={from}&to={to}     BlockHeader[]  
Find blocks before the specified date GET blocks/before/{when}     BlockHeader[]  
Find blocks after the specified date GET blocks/after/{when}     BlockHeader[]  
Find blocks of today GET blocks/today     BlockHeader[]  
Find blocks at the specified date GET blocks/daily/{date}     BlockHeader[]  
Find blocks in the specified month GET blocks/monthly/{date}     BlockHeader[]  

Community Example

POST /circles user

PUT /circles/{circleId} user

POST /circles/{circleId}/invitations user

GET /circles/_/invitations/belongTo/{userId} admin

PUT /circles/_/invitations/{invitationId}/deny

PUT /circles/_/invitations/{invitationId}/accept

POST /circles/{circleId}/memebers

PUT /circles/{circleId}/memebers/{userId}

PUT /circles/belongsTo/{userId}?start={start}&end={end}&pageNo={pageNo}&pageSize={pageSize}

GET /activities/{activityId} admin

GET /activities/count admin

GET /activities?userId={userId}&type={type}&start={start}&end={end}&pageNo={pageNo}&pageSize={pageSize} admin

GET /activites/recent admin

POST /activities admin

PUT /activities/{activityId} admin

GET /activities/mine/{activityId} user

GET /activities/mine/count user

GET /activities/mine?type={type}&start={start}&end={end}&pageNo={pageNo}&pageSize={pageSize} user

GET /activities/mine/recent user

Donation Token Example

Address aware style
API Description
GET /token/accounts/{address}/balance Get the balance of the account in the token
GET /token/accounts/{address}/transfers List the transfers of the account
GET /token/accounts/{senderAddr}/transfers/recipients/{recepientAddr} List the transfers from the specified sender to the specified recepient
GET /token/transfers/-/senders/{senderAddr}/recipients/{recipientAddr}  
POST /token/transfers/-/senders/{senderAddr}/recipients/{recipientAddr}  
Address unaware/corse grained style
API Description
POST /token/transfers/senders/{senderId}/recipients/{recipientId}  
POST /token/trasnfers/senders;id={senderId};type={senderType}/recipients;id={recipientId};type={recipientId}/  
Address unaware/fine grained style
API Description
POST /token/mint-transfers/donors/{donorId}/campaings/{campaignId} Mint tokens to the donor and immediately transfer(donate) the tokens to the campaign
POST /token/transfers/donors/{donorId}/campaigns/{campaignId} Transfer tokens from the donor account to the campaign account
POST /token/trasnfers/campaigns/{campaignId}/projects/{projectId} Trasfer tokes from the campaign account to the project account
GET /token/accounts/donors/{donorId}/balance  
GET /token/accounts/campaings/{campaginId}/balance  
GET /token/accounts/projects/{projectId}/balance  
GET /receipts/donations/{receiptId}  
GET /receipts/donations/donors/{donorId}  

User Service Example

Title Method Path Body Return Remarks
Add a user POST roll/v1/users User(id=null)    
List all users GET roll/v1/users   User[]  
List all valid users GET roll/v1/users/valid   User[]  
List all invalid users GET roll/v1/users/invalid   User[]  
List users of a specific organization GET roll/v1/users?orgId={orgId}   User[]  
List valid users of a specified organization GET roll/v1/valid?orgId={orgId}   User[]  
Find a user GET roll/v1/users/{userId}   User  
Update a user PUT roll/v1/users/{userId} User    
Make a user valid PUT roll/v1/users/{userId}/valid      
Make a user invalid PUT roll/v1/users/{userId}/valid      
Update a user’s password          
Initialize a user’s password          
Get the hash of a user’s password GET roll/v1/users/{userId}/password/sha256   { “hash” : string }  
Add a user email address POST roll/v1/users/{userId}/emails      
List all email addresses of a specified user GET roll/v1/users/{userId}/emails   { “email”: string, “verified”: boolean, “verifiedAt”: date }[]  
Set a user email address verified PUT roll/v1/users/{userId}/emails/{email}/verified      
Remove a user email address DELETE roll/v1/users/{userId}/emails/{email}      
Add a user phone number POST roll/v1/users/{userId}/phones      
List all phone numbers of a specified user GET roll/v1/users/{userId}/phones   { “phone”: string, “verified”: boolean, “verifiedAt”: date }[]  
Set a user phone number verified PUT roll/v1/users/{userId}/phones/{phoneNumber}/verified      
Remove a user phone number DELETE roll/v1/users/{userId}/phones/{phoneNumber}      
Add a user preference POST roll/v1/users/{userId}/preference { “key”: string, “value”: string }[]    
List all common preference keys GET roll/v1/common/PreferenceKeys   { “key”: string, “description”: string }[]  
Add a organization POSt roll/v1/organizations Org    
List all organizations GET roll/v1/organizations   Org[]  
Find an organization GET roll/v1/organizations/{orgId}   Org  
Swagger API
{
   "swagger": "2.0",
   "info": {
      "title": "API for authentication and authorization",
      "description": "The is a API service to manage users, organizations and their authentications and authorizations",
      "contact": {
         "name": "Sangmoon Oh",
         "email": "halfface@chollian.net"
      },
      "version": "0.7"
   },
   "basePath": "/roll/v1",
   "schemas": [
      "https"
   ],
   "consumes": [
      "application/json"
   ],
   "produces": [
      "application/json"
   ],
   "paths": {
      "/users": {
         "post": {
            "description": "Adds a new user",
            "parameters": {
               "name": "user",
               "in": "body",
               "description": "the user to add",
               "schema": {
                  "$ref": "#/definitions/user"
               }
            },
            "responses": {
               "204": {
                  "description": "a user successfully added"
               }
            }
         },
         "get": {
            "description": "Lists all users including invalid users",
            "responses": {
               "200": {
                  "description": "list of all users",
                  "schema": {
                     "$schema": "http://json-schema.org/draft-04/schema#",
                     "type": "array",
                     "items": {
                        "$ref": "#/definitions/user"
                     }
                  }
               }
            }
         }
      },
      "/users/valid": {
         "get": {
            "description": "Lists all valid users",
            "responses": {
               "200": {
                  "description": "list of all valid users",
                  "schema": {
                     "type": "array",
                     "items": {
                        "$ref": "#/definitions/user"
                     }
                  }
               }
            }
         }
      },
      "/users/invalid": {
         "get": {
            "description": "Lists all invalid users",
            "responses": {
               "200": {
                  "description": "list of all invalid users",
                  "schema": {
                     "type": "array",
                     "items": {
                        "$ref": "#/definitions/user"
                     }
                  }
               }
            }
         }
      }
   },
   "defintions": {
      "user": {
         "type": "object",
         "required": [
            "id",
            "name"
         ],
         "properties": {
            "id": {
               "description": "unique identifier of the user",
               "type": "string"
            },
            "name": {
               "description": "name of the user",
               "type": "string",
               "maxLength": 256
            },
            "isValid": {
               "description": "whether this user is valid and approved to access the system or not",
               "type": "boolean",
               "default": false
            },
            "passwordExpired": {
               "description": "whether or not the password of this user is expired and so the password rest is necessary",
               "type": "boolean",
               "default": false
            },
            "registeredAt": {
               "description": "the date-time when the user is registered - the value is in UTC00:00 or ",
               "type": "string",
               "format": "date-time",
               "pattern": "[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]Z"
            },
            "expireAt": {
               "description": "the date-time when the user will be expired",
               "type": "string",
               "format": "date-time"
            },
            "email": {
               "description": "most favorite email address of the user",
               "type": "string",
               "format": "email"
            },
            "extraEmails": {
               "description": "extra email addresses of the user",
               "type": "array",
               "items": {
                  "type": "string",
                  "format": "email"
               }
            },
            "emailValidations": {
               "description": "email validation history of the user"
            },
            "phoneNumber": {
               "type": "string"
            },
            "extraPhoneNumbers": {
               "type": "array",
               "items": {
                  "type": "string"
               }
            },
            "phoneNumberValidations": {

            }
         }
      }
   }
}