Diseñar API REST de la manera correcta

Diseñar API REST de la manera correcta

@programacion

La comunicación web moderna entre el cliente y el servidor se lleva a cabo principalmente con la ayuda de API [interfaces de programación de aplicaciones]. Los modelos de negocio/resultados de la lógica de negocio se exponen a los clientes a través de las apis. Las API deben estar bien diseñadas para admitir la independencia de la plataforma y la evaluación del servicio en primer lugar.

Hay algunas formas en que se puede diseñar una API, REST [Representational State Transfer] es un estilo arquitectónico mediante el cual las API se pueden diseñar bien. Ya sea que sea un programador pragmático o idealista, siempre se requiere tener el diseño arquitectónico básico con todos los casos extremos cuidadosamente considerados para cualquier servidor API.

Las API REST son representaciones de recursos en cualquiera de los formatos conocidos [como el formato JSON] y se transfieren a diferentes sistemas en un entorno de implementación distribuido. No es un protocolo como HTTP, sino un enfoque arquitectónico, pero REST se puede utilizar a través de HTTP.

Por qué es importante el diseño de la API REST:

En estos días, los sistemas de software se desarrollan de manera acelerada, lo que a veces conduce a código repetido, múltiples API expuestas para el mismo recurso, interfaz cliente/usuario que realiza las manipulaciones de datos, etc. Para evitar tales preocupaciones, surge la importancia de diseñar las API REST de manera adecuada, el diseño de las API REST es un factor realmente importante en cualquier sistema distribuido.

Un arquitecto/diseñador comienza solo con las necesidades comerciales y los clientes que utilizan el sistema en mente. En primer lugar, la responsabilidad de la interfaz de usuario y el sistema de almacenamiento de datos debe entenderse bien antes de comenzar a diseñar, y los modelos de datos con respecto al negocio deben identificarse con la consideración cuidadosa de los recursos necesarios.

Los recursos pueden o no correlacionarse directamente con los modelos de datos, y además, todos los recursos del sistema no están necesariamente expuestos a los clientes. Cada recurso debe identificarse con un identificador único, es decir, la URL o el punto final. REST se centra en los componentes, conectores y datos en lugar de las implementaciones o la sintaxis del protocolo.

Elementos arquitectónicos de la API REST:

Elementos de datos: REST transfiere la representación de un recurso en cualquier formato de datos existente, según las capacidades de la interfaz de cliente / usuario. Los diferentes elementos de datos en la arquitectura REST son los siguientes:

Como vemos los elementos arquitectónicos, los recursos [los datos reales] juegan el papel principal. Los recursos se modifican/manipulan/proporcionan utilizando los métodos de solicitud HTTP como GET, POST, PUT, PATCH, DELETE, etc.

Analicemos algunas consideraciones clave al diseñar la API REST:

Identificador de recurso:

Un identificador de recurso no es más que la URL/ruta/punto final a través del cual se accede a un recurso en particular. Siempre es necesario seguir la jerarquía y los sustantivos correctos para crear las URL. Por ejemplo, pensemos que estamos diseñando para un portal de compras, los principales recursos para un portal de compras son productos y perfiles de consumidores. El diseño de API para productos puede tomar la forma que se muestra a continuación:

  1. Lista de los productos

GET /products

2. Enumere los detalles del producto en particular [diga ID de producto como 12],

GET /products/12

3. Enumera los comentarios de los consumidores sobre el producto con Id. De producto

GET /products/12/comments

4. Para ver el comentario particular para el producto con id-producto 12

GET /products/12/comments/3

En los ejemplos anteriores, pudimos ver que los sustantivos se usan y siempre están en plural. Ya sea que enumere muchos productos o proporcione los detalles de un solo producto [GET /products/12], el literal debe ser plural. Si lo hubiera notado, la jerarquía está claramente definida, los productos tienen comentarios del consumidor, también puede haber múltiples comentarios. En el ejemplo anterior, verá el punto 4, que identifica un comentario en particular para un producto específico.

No utilice ningún verbo de acción para las rutas de la API, como "GET /getAProduct", es una mala práctica y no hay límites para crear dichos nombres y los usuarios [clientes] pueden confundirse acerca de cuáles podrían ser los resultados de la API en particular. .

http://www.example.api.com/v1/products //Bueno

http://www.example.api.com/v1/create-product //Malo

Cada uno de los métodos de solicitud HTTP en sí tiene una acción específica y ese nombre significa [qué acción / operación hace] como se muestra a continuación,

POST → Crea un recurso representado por los detalles proporcionados por el cliente, el cuerpo de la solicitud puede tener las propiedades particulares del recurso que deben crearse

GET -> Listas u obtener los recursos/propiedades de los recursos.

PUT -> Crea o reemplaza el recurso existente por el servidor a los detalles del cliente, el cuerpo del mensaje de solicitud puede tener los detalles del recurso para ser creado o reemplazado.

PATCH -> Actualiza o cambia parcialmente los detalles específicos del recurso, el cuerpo del mensaje de solicitud puede tener los detalles que se cambiarán para el producto existente.

DELETE -> elimina el recurso particular para la identificación proporcionada.

Representaciones:

Representaciones significa que la forma / formato en el que se solicitan los recursos o la respuesta se devuelve. Los parámetros del cuerpo, los parámetros de consulta o los parámetros de ruta son las representaciones de la solicitud. De la misma forma, el cuerpo de respuesta representa los recursos resultantes.

Una API POST con parámetros corporales en formato JSON como se muestra a continuación es cómo el cliente representa el recurso.

PPOST-https://example.api.com/v1/products HTTP/1.1

Content-Type: application/json; charset=utf-8

Content-Length: 57

{“Id”:1,”Name”:”CoolPhone”,”Category”:”mobile phones”,”Price”:3000} // Parámetros del body

Del mismo modo, una API GET con parámetros de consulta.

GET https://example.api.com/v1/products?price=3000

Un ejemplo de parámetros de ruta son el producto específico con un productId,

GET https://example.api.com/v1/products/{:id}

Metadatos y datos reales:

Como hasta ahora hemos visto los formatos de entrada / solicitudes desde el extremo del cliente, ahora es la respuesta del servidor para las correspondientes solicitudes recibidas de los clientes, El formato de respuesta puede ser de la forma que tiene tanto la información de alto nivel sobre el recurso resultante [metadatos] y también los detalles reales del recurso [datos].

Ejemplo de respuesta/resultados,

Autenticacion y autorizacion:

Este es uno muy importante en el mundo de las redes abiertas y rápidas, es responsabilidad del servidor API asegurarse de que los datos estén seguros, se transmitan a través de la red de manera segura y lleguen al cliente correcto sin ninguna modificación. Siempre existen amenazas a los datos proporcionados/compartidos a través de la red. Para identificar al cliente adecuado, se requiere tener autenticación y autorización para todas las API.

La autenticación consiste en identificar al cliente mediante identidades específicas del cliente que coinciden con la información de la base de datos del servidor [por ejemplo, ID de usuario/nombre de usuario y contraseña, token de API, etc.]. Puede haber una API como "/login" que puede estar disponible públicamente, que puede autenticar al cliente y puede devolver algunos tokens de autorización específicos/token de sesión, etc.

Una forma de autorización o acceso para las API puede basarse en los tokens proporcionados por el cliente [proporcionados como respuesta en la API de inicio de sesión] o en cualquier información adicional de encabezado de autorización agregada por el cliente. El cliente debe proporcionar la misma información /token al acceder a la API.

Límites de acceso a la API:

Si alguien hace un mal uso de la API o quiere hacer que el servidor caiga por accidente/maliciosamente, no debería haber espacio para ello. Las API deben tener límites para el acceso continuo o exceder el número de solicitudes de API del mismo cliente. El usuario debe ser notificado con 503 respuestas.

API que consumen mucho tiempo:

Puede haber algunas API que pueden tardar algún tiempo en procesar los datos extraídos de la base de datos o manipular y proporcionar los resultados. En esos casos, la API debe responder con el "202 aceptado" como respuesta inmediata, y también debe proporcionar el URI para obtener los resultados. El encabezado de ubicación en la respuesta puede hacer que el URI obtenga los resultados en un momento posterior. Como se muestra en el siguiente ejemplo, donde la respuesta a la API es "202 aceptado", pero no se proporcionan resultados inmediatos, en su lugar, el cliente ha proporcionado información de ubicación para obtener los resultados un poco más tarde.

HTTP/1.1 202 Accepted

Location: /api/v1/status/56789

Paginación y filtro:

El rendimiento es un factor crucial para cualquier sistema que se ocupe de un número creciente de clientes y un volumen de datos. Se puede manejar un número creciente de clientes cuidando la escalabilidad del sistema, probablemente agregando recursos adicionales/duplicando los recursos, etc. Pensemos en el segundo, el volumen de datos, cuando tratamos con los informes o datos estadísticos. siempre el número de registros será enorme. En tales situaciones, es realmente importante que la API no tome tanto tiempo o que no obtenga una mayor cantidad de datos en un momento dado. Por lo tanto, es necesario utilizar las técnicas de paginación junto con las opciones de filtro en la consulta. Por ejemplo, si se necesita una lista más grande de todos los productos, entonces el cliente puede enviar una compensación y un límite mientras se invoca la API como se muestra a continuación,

GET https://example.api.com/v1/products?limit=30&offset=0

GET https://example.api.com/v1/products?limit=30&offset=31

Contenido parcial binario:

Otro factor que debemos considerar al manejar los tipos binarios de datos es responder con contenido parcial. Supongamos que una API proporciona una imagen o archivos más grandes como respuesta; en esos casos, también se debe considerar la capacidad de recepción del cliente, lo que ayudará a generar fragmentos de datos binarios mientras se proporciona la respuesta. El cliente debe proporcionar un encabezado Accept-Ranges en su solicitud GET, esta opción le dirá al servidor que el cliente puede admitir contenido parcial en recepción. También hay otra opción en el método HTTP el “HEAD”, también es similar a GET, etc., ayuda al cliente a saber cuál podría ser el tamaño de la imagen o archivo. Según la respuesta de HEAD API, los clientes pueden decidir cuánto contenido se puede recuperar a la vez y cuántas veces.

HEAD https://example.com/api/v1/products/12?fields=productImage HTTP/1.1

La respuesta puede ser la siguiente:

HTTP/1.1 200 OK

Accept-Ranges: bytes

Content-Type: image/jpeg

Content-Length: 4338

Con la respuesta anterior, el cliente puede decidir cuántos datos se pueden recuperar en el primer intento, como se muestra a continuación:

GET https://example.com/api/v1/products/12?fields=productImage HTTP/1.1

Range: bytes=0–1999

Aquí, la solicitud GET obtiene los primeros 2000 bytes que pueden ser la capacidad de recepción y procesamiento del cliente. Los metadatos de respuesta GET pueden ser los siguientes:

HTTP/1.1 206 Partial Content

Accept-Ranges: bytes

Content-Type: image/jpeg

Content-Length: 2000

Content-Range: bytes 0–2000/4338

Al recibir los primeros 2000 bytes, los clientes pueden emitir otra solicitud GET con un rango de 2000–4338 para obtener el contenido completo de la imagen.

Códigos de respuesta:

Las API del servidor deben enviar el código de respuesta HTTP correcto mientras devuelven las respuestas al cliente. Códigos de respuesta HTTP, en general, tiene principalmente 5 clases como se muestra a continuación,

  1. 1XX => Código de respuesta utilizado para transmitir mensajes informativos, como continuar el procesamiento, etc. Eso significa que el servidor aún está procesando la solicitud.
  2. 2XX => Las respuestas correctas, como OK, creado, aceptado, contenido parcial, etc., significa que la solicitud se ha procesado correctamente y se ha respondido.
  3. 3XX => Los mensajes de redireccionamiento se transmiten con respuestas 3XX. Como movido permanentemente, redireccionamiento temporal, etc., eso significa ponerse en contacto con otro punto final para obtener la información.
  4. 4XX => Códigos de respuesta utilizados para transmitir algo incorrecto en la solicitud realizada por el cliente, un error del cliente
  5. 5XX => Código para transmitir que el servidor tiene algún problema, como un error interno del servidor

Es mejor transmitir las respuestas con los códigos de respuesta correctos para que se entienda correctamente por parte del cliente y también se entienda globalmente.

Puede haber algunas situaciones en las que el servidor ha recibido la solicitud del cliente y el procesamiento de la solicitud puede llevar más tiempo de lo habitual, en esos casos para evitar el tiempo de espera en el extremo del cliente, es una buena práctica enviar "102 ”Código como respuesta.

A continuación se enumeran algunos códigos de respuesta importantes y de uso frecuente:

https://developer.mozilla.org/es/docs/Web/HTTP/Status

Control de versiones:

La menor prioridad, pero sigue siendo importante para admitir la compatibilidad con versiones anteriores, suponga que el diseño evoluciona para admitir diferentes funcionalidades adicionales en el sistema, podríamos terminar agregando algunas características más en las mismas API. En tales casos, el cliente más antiguo [versiones anteriores] puede continuar funcionando sin ningún problema hasta que se actualice a la última versión si existe una versión adecuada. Para admitir la compatibilidad con versiones anteriores, considere la posibilidad de crear versiones de la API. Hay pocas formas:

  1. Control de versiones en los parámetros de la ruta

Por ejemplo, GET http://example.com/api/v1/products

2. Control de versiones en los parámetros de consulta,

Por ejemplo, GET http://example.com/api/products?version=1]

3. Control de versiones del encabezado

Por ejemplo, GET http://example.com/api/products

Custom-Header: api-version=1

4. Control de versiones del tipo de medio.

Por ejemplo, GET http://example.com/api/products

Accept: application/image.v1+json

Documentación:

La mayoría de las veces es un contrato entre el desarrollador de la interfaz de usuario y el desarrollador del sistema sobre cómo se definen las interfaces, cómo serán la solicitud y la respuesta. Mientras se desarrolla la API, es una buena práctica incluir documentación de la API, también ayuda a comprender las diferencias de versiones. Hay muchas herramientas para hacer documentación de API, una de ellas es swagger.io. Desde la versión 2 de swagger, se sigue el estándar API abierto. La iniciativa Open API se crea para estandarizar la API REST en diferentes proveedores.

Espero que esta guía ayude a diseñar API REST maduras y también de una manera estándar de la industria.

Referencias:

https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design

https://mathieu.fenniak.net/the-api-checklist/

https://medium.com/hashmapinc/rest-good-practices-for-api-design-881439796dc9

https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

https://florimond.dev/blog/articles/2018/08/restful-api-design-13-best-practices-to-make-your-users-happy/


Report Page