REST API Guidelines #541

Closed
opened 2023-11-20 10:56:04 +00:00 by hsjobeki · 1 comment
Owner

API Guidelines

This issue serves to collect our common understanding how to design our API so that it is extensible and usable and understandable.

Resource oriented

A resource-oriented API is generally modeled as a resource hierarchy, where each node is either a simple resource or a collection resource. For convenience, they are often called a resource and a collection, respectively.

Examples of Resource Nouns:

machine
user
flake

Often resources have sub-resources. Even if it is not foreseen, it is recommended to use plural (trailing s) on resources to allow them to be collections of sub-resources.

e.g,

users
->
users/*/profile

Verbs

Verbs should not be part of the URL

Bad:
/api/create-products

Good:
/api/products

Only resources are part of the URL, verbs are described via the HTTP Method.

Exception:

If a different HTTP Method must be used for technical reasons it is okay to terminate the path with a (short) verb / action.

Okay ish:
/api/products/create

Usually the following HTTP Methods exist to interact with a resource

  • POST (create an order for a resource)
  • GET (retrieve the information)
  • PUT (update and replace information)
  • PATCH (update and modify information) (Not used yet)
  • DELETE (delete the item)

Every resource should be CRUD compatible

All API resources MUST be designed in a way that allows the typical CRUD operations.

Where crud stands for:

C - Create
R - Read
U - Update
D - Delete

Resources should implement at least a "Read" operation.

Body

Use JSON as an exchange format.

All responses MUST be JSON parseable.

Bad:
bare string

Better:
"quoted string"

Best: (Enveloped see next section)
{ name: "quoted string"}

Errors should have a consistent JSON format, such that it is clear in which field to look at for displaying error messages.

Envelop all Data collections

Response data should be wrapped into an JSON Object {}
Lists [] should also contain Objects {}.
This allows everything, to be extensible, without breaking backwards compatibility. (Adding fields is trivial, since the schema doesn't change)

Example:

{
   "users": [{
     first_name: "John",
     last_name: "Doe",
     …
   }, {
     first_name: "Jane",
     last_name: "Doe",
     …
   }
  ....
  ],
   "skip": 0,
   "limit": 20,
  ....
}

Bad Example of a breaking change:
GET /api/flakes
old

[
  "dream2nix"
  "disko"
]

new

[
 {
    name: "dream2nix",
    url: "github/...."
 },
 {
    name: "disko",
    url: "github/...."
 }
]

Those kind of breaking changes can be avoided by using an object from the beginning.
Even if the object only contains one key, it is extensible, without breaking.

More will follow.

# API Guidelines This issue serves to collect our common understanding how to design our API so that it is extensible and usable and understandable. ## Resource oriented A resource-oriented API is generally modeled as a resource hierarchy, where each node is either a simple resource or a collection resource. For convenience, they are often called a resource and a collection, respectively. Examples of Resource Nouns: `machine` `user` `flake` Often resources have sub-resources. Even if it is not foreseen, it is recommended to use plural (trailing `s`) on resources to allow them to be collections of sub-resources. e.g, `users` -> `users/*/profile` ## Verbs Verbs should not be part of the URL Bad: `/api/create-products` Good: `/api/products` Only resources are part of the URL, verbs are described via the HTTP Method. Exception: If a different HTTP Method must be used for technical reasons it is okay to terminate the path with a (short) verb / action. Okay ish: `/api/products/create` ## Usually the following HTTP Methods exist to interact with a resource - POST (create an order for a resource) - GET (retrieve the information) - PUT (update and replace information) - PATCH (update and modify information) **(Not used yet)** - DELETE (delete the item) ## Every resource should be CRUD compatible All API resources MUST be designed in a way that allows the typical CRUD operations. Where crud stands for: C - Create R - Read U - Update D - Delete Resources should implement at least a "Read" operation. ## Body Use JSON as an exchange format. All responses MUST be JSON parseable. Bad: `bare string` Better: `"quoted string"` Best: (Enveloped see next section) `{ name: "quoted string"}` Errors should have a consistent JSON format, such that it is clear in which field to look at for displaying error messages. ## Envelop all Data collections Response data should be wrapped into an JSON Object `{}` Lists `[]` should also contain Objects `{}`. This allows everything, to be extensible, without breaking backwards compatibility. (Adding fields is trivial, since the schema doesn't change) Example: ``` { "users": [{ first_name: "John", last_name: "Doe", … }, { first_name: "Jane", last_name: "Doe", … } .... ], "skip": 0, "limit": 20, .... } ``` Bad Example of a breaking change: `GET /api/flakes` `old` ``` [ "dream2nix" "disko" ] ``` `new` ``` [ { name: "dream2nix", url: "github/...." }, { name: "disko", url: "github/...." } ] ``` Those kind of breaking changes can be avoided by using an object from the beginning. Even if the object only contains one key, it is extensible, without breaking. ## More will follow.
Mic92 was assigned by hsjobeki 2023-11-20 10:56:12 +00:00
lassulus was assigned by hsjobeki 2023-11-20 10:56:12 +00:00
Qubasa was assigned by hsjobeki 2023-11-20 10:56:12 +00:00
DavHau was assigned by hsjobeki 2023-11-20 10:56:12 +00:00
hsjobeki self-assigned this 2023-11-20 10:56:12 +00:00
kenji was assigned by hsjobeki 2023-11-20 10:56:12 +00:00
Owner

Opened a PR putting the guidelines in our docs: #595

Opened a PR putting the guidelines in our docs: https://git.clan.lol/clan/clan-core/pulls/595
Sign in to join this conversation.
No Milestone
No project
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: clan/clan-core#541
No description provided.