Beruflich Dokumente
Kultur Dokumente
que nos permitan acceder a información o datos concretos usando métodos HTTP como POST, GET, PUT y DELETE para operar
con los recursos. Estos métodos son equiparables a las operaciones CRUD (Create, Read, Update, Delete) de las bases de datos.
Aclarado esto, empecemos con las recomendaciones.
Por cuestiones de mejor comprensión y legibilidad de la semántica de la API, usa sólo nombres para toda su estructura.
/getAllCars
/createNewCar
/deleteAllRedCars
La propia semántica que compone la URL, junto con el método HTTP usado (POST, GET, PUT, DELETE), permite prescindir
de verbos como “create”, “get”, “update” y “delete”.
GET /users/711?activate
GET /users/711/activate
Cuál usar dependerá del diseño de la base de datos o la lógica con la que se estructura el almacenamiento de la misma.
No mezcles nombres en singular con nombres en plural. Hazlo simple y mantén los nombres en plural.
En vez de usar:
/car
/user
/product
/setting
Usa el plural:
/cars
/users
/products
/settings
El uso del plural te permitirá posteriormente hacer operaciones del tipo:
/cars/<id>
/users/<id>
/products/<id>
/settings/<name>
Si un recurso está relacionado con otro, usa subrecursos montados sobre la estructura de la URL.
Tanto la parte cliente como la del servidor, necesitan saber en qué formato se están pasando los datos para poder comunicarse. Lo
más sencillo es especificarlo en la cebecera HTTP.
Content-Type: Define el formato de la petición.
Accept: Define la lista de formatos aceptados en la respuesta.
Usar HATEOAS
El uso de HATEOAS (Hypermedia as the Engine of Application State) es un diseño que nos permite incluir el principio
de hipervínculos de manera similar a la navegación web, lo que nos permite una mejor navegación por la API.
En este ejemplo la respuesta en formato JSON nos devuelve junto con la información del equipo con id 5000, una serie de
referencias a recursos relacionados, como pueden ser el estadio del equipo o sus jugadores. Normalmente se suele agrupar todas
las referencias dentro de una propiedad o atributo llamada “links“.
1 {
2 "links": [{
3 "rel": "self",
4 "href": "http://localhost:8080/soccer/api/teams/5000"
5 }, {
6 "rel": "stadium",
7 "href": "http://localhost:8080/soccer/api/teams/5000/stadium"
8 }, {
9 "rel": "players",
10 "href": "http://localhost:8080/soccer/api/teams/5000/players"
11 }],
12 "teamId": 5000,
13 "name": "Real Madrid C.F.",
14 "foundationYear": 1902,
15 "rankingPosition": 1
16 }
Este tipo de diseño está pensado para la longevidad del software y la evolución independiente, ya que frecuentemente en la
arquitectura de sistemas y servicios, es a corto plazo lo que más suele fallar.
Filtrado
Utilizar un parámetro de consulta único para todos los campos o un lenguaje de consulta formalizado para filtrar.
GET /cars?sort=-manufactorer,+model
En el ejemplo se devuelve una lista de coches ordenada con los fabricantes de manera descendiente y los modelos de manera
ascendente.
Selección de campos
Permitir la selección de unos pocos campos de un recurso si no se precisan todos. Dar al consumidor de la API la posibilidad de
qué campos quiere que se devuelvan, reduce el volumen de tráfico en la comunicación y aumenta la velocidad de uso de la API.
GET /cars?fields=manufacturer,model,color
En el ejemplo se pide la lista de coches, pero pidiendo sólo los campos de “fabricante“, “modelo” y “color“.
Paginación
Uso de “offset” para establecer la posición de partida de una colección y “limit” para establecer el número de elementos de la
colección a devolver desde el offset. Es un sistema flexible para el que consume la API y bastante extendido entre los sistemas de
bases de datos.
GET /cars?offset=10&limit=5
En el ejemplo se devuelve una lista de coches correspondiente a los coches comprendidos de la posición 10 a la 15 de la
colección.
Para devolver al consumidor de la API el número total de entradas se puede usar la cabecera HTTP “X-Total-Count” y para
completar la información proporciona, por ejemplo, devolver los enlaces a la página previa y siguiente, entre otros, usando la
cabecera HTTP “Link“.
Link:
<http://localhost/sample/api/v1/cars?offset=15&limit=5>; rel="next",
<http://localhost/sample/api/v1/cars?offset=5&limit=5>; rel="prev",
<http://localhost/sample/api/v1/cars?offset=50&limit=3>; rel="last",
<http://localhost/sample/api/v1/cars?offset=0&limit=5>; rel="first",
Como alternativa es posible usar HATEOAS, como ya he comentado anteriormente.
Versionar la API
Es muy recomendable, tirando a obligatorio , el poner versión de API y no liberar APIs sin versión. Usa un simple número
para especificar la versión y no uses un versionado tipo semver del tipo 1.5.
Si se usa la URL para marcar la versión, pon una “v” precediendo el número de versión.
/blog/api/v1
Es la forma más sencilla y eficaz de asegurar la compatibilidad en el versionado de la API. Especificarla como parámetro o en la
petición y/o en la respuesta, conlleva el aumento del tráfico y el coste de computación, al tener que existir lógica para discriminar
las distintas versiones soportadas sobre una misma URL.
Es difícil trabajar con una API que ignora el manejo de errores, por no decir imposible . La devolución de un código HTTP
500 para cualquier tipo de error o acompañado de una traza de error del código del servidor no es muy útil, además de que puede
ponernos en peligro ante una vulnerabilidad que un atacante quisiera explotar.
Usar códigos de estado HTTP
El estándar HTTP proporciona más de 70 códigos de estado para describir los valores de retorno. En general no los utilizaremos
todos, pero se debe utilizar por lo menos un mñinimo de 10, que suelen ser los más comunes:
Todas las excepciones deben ser asignadas en un payload de error. A continuación, se muestra un ejemplo de cómo podría verse
un payload de error en formato JSON:
1 {
2 "errors": [
3 {
4 "userMessage": "Sorry, the requested resource does not exist",
5 "internalMessage": "No car found in the database",
6 "code": 34,
7 "more info": "http://dev.mascandobits.es/blog/api/v1/errors/12345"
8 }
9 ]
10 }
Algunos proxys sólo admiten métodos POST y GET. Para que una API RESTful funcione con estas limitaciones, la API necesita
una forma de sustituir el método HTTP.
Una opción es utilizar la cebecera HTTP “X-HTTP-Method-Override” para sobrescribir el método POST y así personalizar la
petición POST para que cumpla, por ejemplo, una operación DELETE.
X-HTTP-Method-Override: DELETE