General Guidelines:
for unknown attributes in the request, we will throw a bad request error.
for all the response, we will add related HATEOAS link to each configuration responses, such as: return resource link in the response of create/list/get; add resource url for sub resources(region/indexes). more detail, please read "HATEOAS link" in Guidelines for Cluster Management service
http status code: 201 and 409 for create, 200 and 404 for delete, 200 and 404 for put to update
- camelCase is for all the key in the request and response body
HATEOAS link
for every relation between entities, will be shown as links in the output of response.
such as the followings, it is a links part of region and it shows that the related links of current entity(region):
"links": { "indexes": "http://127.0.0.1:7070/management/experimental/regions/REGION6/indexes", "self": "http://127.0.0.1:7070/management/experimental/regions/REGION6", "list": "http://127.0.0.1:7070/management/experimental/regions" }
some guideline for links:
- the "links" part is sibling of "configuration" and "runtimeInfo"
- all the related resources will be shown in "links" part
- every link includes whole address, begins from "http"/"https"
- there must be a "self" link in every "links", the "self" means current resource(entity)
- there must be a "list" link in every "links", it means the resources (list)
- other link in "link" part must be plural(“-es”)
Long running request:
- operations that are long running should not hold up the http connection for the entirety of the operations. The operation will be started and then the response should go back to the user signifying "operation started" with a link to check the status of the operation.
- User will issue the request to the "status" link to check the operation status.
Groups:
When an entity is defined in multiple groups, for example, a region can be defined in multiple groups, when we issue a GET to the "/regions/regionA", it's expected that we should only get one entity back. But since the region is defined in multiple groups, and could potentially have different configurations per group, the configuration for this region can be multiple. So we should try to lump all the configurations for one entity into one entity response back to the user.
Here is an example how the response would look like to the user when a region belongs to multiple groups:
{ "statusCode": "OK", "result": [{ "id": "region-with-proxy", "groups": [{ "configuration": { "group": "group2", "name": "region-with-proxy", "type": "PARTITION" }, "runtimeInfo": [{ "entryCount": 10 }] }, { "configuration": { "group": "group1", "name": "region-with-proxy", "type": "PARTITION_PROXY" }, "runtimeInfo": [{ "entryCount": 10 }] }], "links": { "indexes": "http://localhost:22500/management/v1/regions/region-with-proxy/indexes", "self": "http://localhost:22500/management/v1/regions/region-with-proxy", "list": "http://localhost:22500/management/v1/regions" } }, { "id": "region-in-single-group", "groups": [{ "configuration": { "group": "group1", "name": "region-in-single-group", "type": "PARTITION" }, "runtimeInfo": [{ "entryCount": 20 }] }], "links": { "indexes": "http://localhost:22500/management/v1/regions/region-in-single-group/indexes", "self": "http://localhost:22500/management/v1/regions/region-in-single-group", "list": "http://localhost:22500/management/v1/regions" } }, { "id": "region-in-cluster", "groups": [{ "configuration": { "name": "region-in-cluster", "type": "PARTITION" }, "runtimeInfo": [{ "entryCount": 0 }] }], "links": { "indexes": "http://localhost:22500/management/v1/regions/region-in-cluster/indexes", "self": "http://localhost:22500/management/v1/regions/region-in-cluster", "list": "http://localhost:22500/management/v1/regions" } }, { "id": "region-in-multiple-groups", "groups": [{ "configuration": { "group": "group2", "name": "region-in-multiple-groups", "type": "PARTITION" }, "runtimeInfo": [{ "entryCount": 0 }] }, { "configuration": { "group": "group1", "name": "region-in-multiple-groups", "type": "PARTITION" }, "runtimeInfo": [{ "entryCount": 0 }] }], "links": { "indexes": "http://localhost:22500/management/v1/regions/region-in-multiple-groups/indexes", "self": "http://localhost:22500/management/v1/regions/region-in-multiple-groups", "list": "http://localhost:22500/management/v1/regions" } }] }
References:
1 https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md
2 https://developer.github.com/v3/
3 https://codeplanet.io/principles-good-restful-api-design/
4 https://blog.florimond.dev/restful-api-design-13-best-practices-to-make-your-users-happy
5 https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/