El siguiente artículo podría considerarse una segunda parte espiritual de Script en Bash y cURL para hacer comprensiva una API. En este caso, se trata de un ejemplo sencillo en Markdown de cómo documentar una API orientado a desarrolladores. Lo utilizo como base para documentar en mis proyectos donde no uso, no puedo, no debo, usar OpenAPI o Swagger.
Trabajamos con una API REST que sirve tres recursos: Client
, User
y Role
. Algunos endpoints tienen parámetros y otros no. Los métodos permitidos son GET
, POST
, PUT
y DELETE
. Los campos de las respuestas son ficticios y se han simplificado para su comprensión. No todas las rutas siguen una estructura CRUD (o si sientes más empatía por el frontend, BREAD).
# API
## Client
### `/api/v1/clients/`
GET - List all clients
#### Parameters
Nothing
#### Request body
```json
{}
```
#### Response
```json
[
{
"id": 1,
"alias": "Client 1",
"name": "Client 1 description",
"logo": {
"dark": "http://localhost:8000/media/clients/1/logo_dark.png",
"light": "http://localhost:8000/media/clients/1/logo_light.png"
},
},
{
"id": 2,
"alias": "Client 2",
"name": "Client 2 description",
"logo": {
"dark": "http://localhost:8000/media/clients/2/logo_dark.png",
"light": "http://localhost:8000/media/clients/2/logo_light.png"
},
}
]
```
### `/api/v1/clients/{id}/`
GET - Retrieve a client
#### Parameters
- `id` - The client id
#### Request body
```json
{}
```
#### Response
```json
{
"id": 1,
"alias": "Client 1",
"name": "Client 1 description",
"logo": {
"dark": "http://localhost:8000/media/clients/1/logo_dark.png",
"light": "http://localhost:8000/media/clients/1/logo_light.png"
},
}
```
## Users
### `/api/v1/users/`
GET - List users
#### Parameters
- `query` - The search query by `email`, `first name` or `last name`. Default is `""`.
- `page` - The page number. Default is `1`.
- `perPage` - The number of items per page. Default is `10`.
- `orderBy` - The field to order by. Default is `email`. Possible values are `email`, `first name`, `last name`, `is active` and `created at`.
- `order` - The order. Default is `asc`. Possible values are `asc` and `desc`.
#### Request body
```json
{}
```
#### Response
```json
{
"page": 1,
"total": 12,
"perPage": 10,
"lastPage": 2,
"results": [
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
},
]
}
```
### `/api/v1/users/{id}/`
GET - Retrieve a user
#### Parameters
- `id` - The user id
#### Request body
```json
{}
```
#### Response
```json
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
}
```
### `/api/v1/users/{id}/`
POST - Create a user
#### Parameters
Nothing
#### Request body
```json
{
"email": "foo@boo.com",
"password": "password",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1
}
```
#### Response
```json
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
}
```
### `/api/v1/users/{id}/`
PUT - Update a user
#### Parameters
- `id` - The user id
#### Request body
```json
{
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1
}
```
#### Response
```json
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
}
```
### `/api/v1/users/{id}/`
DELETE - Delete a user
#### Parameters
- `id` - The user id
#### Request body
```json
{}
```
#### Response
```json
{}
```
### `/api/v1/users/{id}/password/`
PUT - Update a user password
#### Parameters
- `id` - The user id
#### Request body
```json
{
"password": "password"
}
```
#### Response
```json
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
}
```
### `/api/v1/users/{id}/enabled/`
PUT - Set user enabled
#### Parameters
- `id` - The user id
#### Request body
```json
{
"isActive": true
}
```
#### Response
```json
{
"id": 1,
"email": "foo@boo.com",
"firstName": "Foo",
"lastName": "Boo",
"isActive": true,
"roleId": 1,
"createdAt": "2024-11-29T14:41:35.342Z", // ISO 8601
}
```
## Roles
### `/api/v1/roles/`
GET - List all roles
#### Parameters
Nothing
#### Request body
```json
{}
```
#### Response
```json
[
{
"id": 1,
"name": "admin",
"permissions": [
{
"id": 1,
"name": "manage-users"
},
{
"id": 2,
"name": "statistics"
},
{
"id": 3,
"name": "view"
}
]
},
{
"id": 2,
"name": "guest",
"permissions": [
{
"id": 3,
"name": "view"
}
]
}
]
```
Me gustaría destacar algunos puntos:
- Se ha utilizado Markdown para la documentación, pero se podría utilizar cualquier otro formato como Org, Asciidoc, etc.
- Los cuerpos son en JSON, lo cual es muy común en APIs REST. Sin embargo se podrían usar formularios, binarios, etc.
- Las fechas cumplen con el estándar ISO 8601. Las 5 reglas para las fechas y las APIs son:
- Usa ISO-8601 para las fechas.
- Acepta cualquier zona horaria.
- Guarda las fechas en UTC.
- Devuelve las fechas en UTC.
- No uses tiempos si no son necesarios.
- No se han incluido ejemplos de errores, códigos de estado, etc. ¿Quieres incluirlos? ¡Adelante! Sin embargo te recomiendo realizar antes las pruebas unitarias.
- No hay documentación de autenticación o autorización. Sería apropiado añadir una sección para ello, como las rutas de login, logout, refresco de token, tiempos de expiración, etc.
- También sería buena idea incluir una sección con headers necesarios, como
Content-Type
,Accept
oAuthorization
.
Aún queda más trabajo por delante. Sin embargo, hay que empezar con buen pie y con la máxima calidad posible. ¡Ánimo!
Fuente The 5 rules of API dates and times
{{ comments.length }} comentarios