Entendiendo y utilizando RESTful APIs
Yi Sun
December 2, 2022
En la era del Internet de las Cosas, existen muchas API diferentes, y es importante estandarizarlas. La API RESTful es uno de los estilos de arquitectura de API más populares, que puede ayudarte a separar las preocupaciones del lado del cliente y del servidor, permitiendo que el frontend y el backend evolucionen por separado, mejorando así la eficiencia. Su característica sin estado puede hacer que la aplicación sea más escalable y facilite la implementación de políticas de caché para mejorar la experiencia del usuario y el rendimiento. En este artículo, presentaremos qué es una API RESTful y cómo podemos usarla.
¿Qué es una API?
Dejando de lado por un momento qué es una API, hablemos de cómo entregamos información en nuestra vida cotidiana.
Cuando llevas tu dinero al dueño de la tienda y le dices que necesitas comprar pilas, el dueño recibe el dinero, busca las pilas en el estante y te las entrega. Una transacción para comprar una pila se ha completado con éxito.
Por otro lado, el software de computadora completa esto a través de las API. Comencemos con la definición de Wikipedia:
Una interfaz de programación de aplicaciones (API) es una forma en que dos o más programas de computadora se comunican entre sí. Es un tipo de interfaz de software que ofrece un servicio a otras piezas de software.
El Software A hace una solicitud al Software B a través de la API, y el Software B devuelve la respuesta a A a través de la API después de consultar sus recursos.
El Software A haciendo una solicitud al Software B a través de la API es como decirle a tu jefe que necesitas una pila, y el Software B devolviendo los datos al Software A es como tu jefe encontrando la pila y entregándotela.
Este proceso no requiere que el Software B sepa por qué el Software A quiere los datos, al igual que el dueño de la tienda no te preguntaría por qué compraste la pila. El Software A tampoco necesita saber cómo el Software B encontró los datos, al igual que no le preguntarías al dueño de dónde compró las pilas cuando las compraste. Cada software pasa información entre sí a través de las API, y cada uno hace lo suyo, haciendo que el mundo de la programación sea ordenado y confiable.
¿Qué es una API RESTful?
Roy Fielding definió REST (Transferencia de Estado Representacional) en su tesis doctoral del año 2000, "Estilos Arquitectónicos y Diseño de Arquitectura de Software Basada en la Web", y el estilo arquitectónico REST define seis restricciones guía. Un sistema que cumple con algunas o todas estas restricciones se conoce coloquialmente como RESTful.
(Fuente: Seobility)
Restricciones de las API RESTful
Restricciones | Detalles | Beneficios |
---|---|---|
Arquitectura cliente-servidor | Mejora la portabilidad de la interfaz de usuario en múltiples plataformas al separar los problemas de la interfaz de usuario de los problemas de almacenamiento de datos, y mejora la escalabilidad al simplificar los componentes del servidor. | 1. Desacoplamiento del lado del cliente y del servidor. 2. Mejora la portabilidad de las plataformas de usuario entre plataformas. 3. Mejora la escalabilidad del lado del servidor. |
Sin estado | Cada solicitud del cliente al servidor debe contener toda la información necesaria para la solicitud y no debe hacer uso de ningún contexto almacenado en el servidor, y el estado de la sesión se almacena completamente en el cliente. | 1. Fácil de escalar, no hay dependencias de sesión y cualquier servidor puede manejar cualquier solicitud. 2. Fácil de almacenar en caché para mejorar el rendimiento del programa. |
Capacidad de caché | Requiere que los datos en una solicitud o respuesta estén implícita o explícitamente marcados como almacenables en caché o no almacenables en caché. Si una respuesta es almacenable en caché, entonces se otorga al caché del cliente el derecho de reutilizar esos datos de respuesta para solicitudes equivalentes posteriores. | 1. Reduce el ancho de banda. 2. Reduce la latencia. 3. Reduce la carga del servidor. 4. Oculta el estado de la red. |
Sistema en capas | El comportamiento restringido de los componentes permite que la arquitectura se componga de capas para que cada componente no pueda "ver" más allá de la capa inmediata con la que interactúa. Al limitar el conocimiento del sistema a una sola capa, se reduce la complejidad del sistema completo y se promueve la independencia en la base. | 1. Reduce la complejidad del sistema en general. 2. Promueve la independencia en la base. 3. Se puede implementar fácilmente el balanceo de carga. 4. La lógica de negocio y las políticas de seguridad se pueden desacoplar. |
Código bajo demanda (opcional) | Permite que la funcionalidad del cliente se extienda descargando y ejecutando código en forma de applets o scripts. | 1. Mejora la escalabilidad del sistema. |
Interfaz uniforme | Contiene cuatro puntos principales: 1. Identificación de recursos en las solicitudes. Los clientes pueden identificar un recurso por el URI contenido en la solicitud, desacoplando el recurso del lado del servidor del recurso solicitado por el cliente. 2. Manipulación de recursos a través de representaciones. Cuando un cliente tiene la representación de un recurso, como un URI, entonces hay suficiente información para modificar o eliminar el recurso. 3. Mensajes autodescriptivos. Cada mensaje incluye suficiente información para informar al cliente qué hacer con el mensaje. 4. Hipermedia como motor del estado de la aplicación (HATEOAS). El cliente no necesita codificación adicional para hacer que todos los recursos estén disponibles para el usuario a través de los enlaces de recursos devueltos por el servidor. | 1. Simplifica la arquitectura general del sistema. 2. Mejora la visibilidad de las interacciones. |
Mejores Prácticas para API RESTful
El énfasis en interfaces unificadas entre componentes es una característica central que distingue el estilo arquitectónico REST de otros estilos basados en la web, y basándose en esta característica, se han ordenado aquí las mejores prácticas para ayudarte a diseñar mejor tu API.
Evitar Verbos en el Nombre de la Ruta
Usa métodos HTTP para expresar el comportamiento de manipulación de recursos, en lugar de definir verbos de comportamiento en las rutas.
// Bueno
curl -X GET http://httpbin.org/orders
// Malo
curl -X GET "http://httpbin.org/getOrders"
- Obtén la información del recurso para el URI especificado usando GET
// Representa obtener toda la información de pedidos del sistema actual
curl -X GET http://httpbin.org/orders
// Representa obtener la información detallada del pedido número 1
curl -X GET http://httpbin.org/orders/1
- Crea un recurso desde el URI especificado usando POST
// Representa la creación de un recurso con el nombre order
curl -X POST http://httpbin.org/orders \
-d '{"name": "awesome", region: "A"}' \
- Crea o reemplaza completamente recursos en el URI especificado usando PUT
// Representa la sustitución de datos para un pedido con id 1
curl -X PUT http://httpbin.org/orders/1 \
-d '{"name": "new awesome", region: "B"}' \
- PATCH realiza una actualización parcial de un recurso
// Representa cambiar el campo región del pedido con id 1, manteniendo el resto de los datos sin cambios
curl -X PATCH http://httpbin.org/orders/1 \
-d '{region: "B"}' \
- Elimina un recurso especificando un URI usando DELETE
// Representa la eliminación del pedido con id 1
curl -X DELETE http://httpbin.org/orders/1
Usar la Forma Plural en los URIs
Si deseas usar la forma singular para indicar el acceso a un tipo particular de recurso:
curl -X GET "http://httpbin.org/order"
Usar la forma singular confundirá al usuario pensando que solo hay un pedido en el sistema, pero usar la forma plural hará que sea mucho más fácil de entender.
curl -X GET "http://httpbin.org/orders"
Hacer un Buen Uso de los Códigos de Estado HTTP
El estándar HTTP define códigos de estado, que se pueden clasificar en las siguientes categorías:
Códigos de Estado | Significado |
---|---|
2xx | Éxito, la operación fue recibida y procesada con éxito |
3xx | Redirección, se requiere una acción adicional para completar la solicitud |
4xx | Error del cliente, la solicitud contenía un error de sintaxis o no se pudo completar |
5xx | Error del servidor, ocurrió un error mientras el servidor procesaba la solicitud |
Usar códigos de estado estándar permite a los desarrolladores identificar problemas de inmediato y puede reducir el tiempo que lleva encontrar diferentes tipos de errores.
Control de Versiones
A medida que cambian los requisitos del negocio, es muy probable que las API que ya están en línea tengan que ajustarse en consecuencia. Si nuestras API son utilizadas por terceros, obviamente es imposible hacer que cada cliente cambie según los cambios de nuestras API, por lo que es hora de introducir el concepto de gestión de versiones de API, lo que puede garantizar el uso normal de las API históricas e iterar nuevas API para cumplir con los nuevos requisitos del negocio.
Los medios comunes de control de versiones son:
- Control de Versiones a través de Rutas en las Solicitudes
// Solicitar API v1
curl http://httpbin.org/v1/orders
// Solicitar API v2
curl http://httpbin.org/v2/orders
- Control de Versiones a través de Parámetros de Consulta
// Solicitar API v1
curl http://httpbin.org/orders?version=v1
// Solicitar API v2
curl http://httpbin.org/v2/orders?version=v2
- Control de Versiones a través de Cabeceras
// Solicitar API v1
curl http://httpbin.org/orders -H "custom-version: v1"
// Solicitar API v2
curl http://httpbin.org/orders -H "custom-version: v2"
Cómo APISIX Potencia las API RESTful
Apache APISIX es una puerta de enlace API dinámica, en tiempo real y de alto rendimiento. Puede ejecutarse frente a cualquier servicio API RESTful y usar complementos para agregar nuevos servicios y extender su funcionalidad, lo que está en línea con la definición RESTful de Sistema en Capas. Además, para algunos servicios históricos que no siguen la definición de API RESTful, APISIX también puede ayudarte a convertir tu interfaz sin cambiar el código de negocio original para que tu interfaz cumpla con la restricción REST de Interfaz Uniforme, haciendo que tu API cumpla mejor con la especificación de API RESTful.
Sistema en Capas: Soporta la Separación de la Lógica de Negocio y la Lógica de Seguridad
Puedes centrarte solo en la implementación de la lógica de negocio, la lógica de seguridad de la interfaz puede dejarse a los complementos de autenticación de APISIX, por ejemplo, key-auth. APISIX admite una gran cantidad de complementos de Autenticación, tomemos openid-connect como ejemplo, como se muestra en la siguiente figura:
Podemos ver que usar APISIX (Puerta de Enlace API) para agregar una capa de lógica de autenticación frente a nuestro servidor de negocio puede servir para proteger los servicios ascendentes, y este patrón arquitectónico puede ser una buena manera de desacoplar tu lógica de negocio de la lógica de seguridad.
Sistema en Capas: Soporte de Múltiples Protocolos de Balanceo de Carga
APISIX, como puerta de enlace API, puede configurarse entre el lado del cliente y el servidor para cumplir con diferentes requisitos de carga. Incluso puedes personalizar la lógica de balanceo de carga.
Los algoritmos de balanceo de carga admitidos son:
roundrobin
: Balanceo de carga round robin con pesos.chash
: Hash consistente.ewma
: Selecciona el nodo con la latencia mínima. Consulta Gráfico EWMA para más detalles.least_conn
: Selecciona el nodo con el valor más bajo de(active_conn + 1) / weight
. Aquí, una conexión activa es una conexión que está siendo utilizada por la solicitud y es similar al concepto en Nginx.- Balanceador de carga personalizado cargado a través de
require("apisix.balancer.your_balancer")
Interfaz Uniforme: Hacer que las API Históricas sean Más RESTful
Para las API históricas que han estado alrededor por mucho tiempo y no siguen bien las pautas de API RESTful, puedes reencapsular la nueva API a través de APISIX para cumplir con diferentes escenarios de negocio sin modificar la lógica original de la API.
- Usa proxy-rewrite para reescribir las solicitudes del cliente
Como se mencionó anteriormente, no deberíamos tener verbos en nuestra ruta.
Por ejemplo, si la API histórica tiene la interfaz /getOrder
, podemos redirigir la solicitud de la API a la API histórica a través del complemento proxy-rewrite.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"proxy-rewrite": {
"uri": "/getOrder",
"scheme": "http",
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
También puedes usar el complemento para operaciones de versionado de API.
- Usa el complemento response-rewrite para reescribir las respuestas del servidor
Cuando nuestra API histórica tiene códigos de estado de respuesta no estandarizados, podemos usar response-rewrite para redirigir la respuesta y modificar el código de estado de la respuesta.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"response-rewrite": {
"status_code": 201,
"body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
"vars":[
[ "status","==",200 ]
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
El ejemplo anterior representa una solicitud para modificar el estado de 200 a 201 en la API que solicita la ruta /orders.
Dado que APISIX admite complementos muy ricos, espero que explores más formas de jugar.
Resumen
Este artículo introduce qué es una API, qué es una API RESTful y sus mejores prácticas. Además, este artículo también introduce cómo separar la lógica de negocio y la lógica de seguridad a través de APISIX, y cómo usar APISIX para hacer que los servicios de API históricos sean más RESTful sin cambiar el código de negocio original. Espero que este artículo te ayude a comprender las API RESTful.