Escolar Documentos
Profissional Documentos
Cultura Documentos
API
Application Programming Interface
Es la abstracción de una implementación
Existen muchos tipos:
Sistema operativo
Entornos de programación
Servicios web
Arquitectura REST
REST (REpresentational State Transfer) es un tipo de arquitectura de
desarrollo web que se apoya totalmente en el estándar HTTP. REST nos
permite crear servicios compatibles con cualquier dispositivo o cliente
HTTP, por lo que es mucho más sencillo que antiguas alternativas, como
SOAP y XML-RPC.
Cliente-Servidor
Sin estado
Cacheable
El cliente puede querer cachear las respuestas, por lo que estas deben
ser cacheables. Es decir, debe incluirse en los headers de las
respuestas la cabecera Last-Modified y soportar la recepción de la
cabecera If-Unmodified-Since en las peticiones GET del cliente.
Interfaz uniforme
Identificación de recursos
Manipulación de recursos mediante su representación
Mensajes autodescriptivos
Hipermedia como motor de estado
Sistema de capas
Código en demanda
Para que un servicio sea considerado RESTful debe cumplir una serie de
requisitos:
<protocolo>://<hostname>[:puerto]/<ruta_del_recurso>.
Métodos HTTP
Códigos de estado
Formatos de contenido
Métodos HTTP
HTTP pone a nuestra disposición 5 métodos o "verbos":
GET: Para leer un recurso
HEAD: Para leer metainformación de un recurso
POST: Para crear un recurso
PUT: Para editar un recurso
DELETE: Para eliminar un recurso
PATCH: Para editar partes de un recurso
Códigos de estado
Para que un servicio pueda ser considerado RESTful es vital que haga un
uso correcto de los códigos de estado
(http://es.wikipedia.org/wiki/Anexo%3aC%C3%B3digos_de_estado_HTTP)
que ofrece HTTP. Existe un código preestablecido para cada posible
situación a la que nuestro servicio tenga que enfrentarse. Estos códigos se
agrupan de la siguiente forma (sólo se enumeran algunos):
200: OK
201: Elemento creado
202: Petición aceptada, pero aún se está procesando. Podría no
completarse si se produce algún error
203: Información no autoritativa. La respuesta ha recibido alguna
transformación por parte de un proxy
204: Respuesta vacía
205: El servidor solicita al cliente que recargue la página
206: Contenido parcial. Utilizado para dividir una descarga o
interrumpirlas y reanudarlas
207: Estado múltiple. El cuerpo es un XML con subcódigos de
estado, dependiendo de las sub-peticiones hechas
3XX: Redirecciones. El cliente tiene que realizar una acción adicional.
No está permitido hacerlo más de 5 veces seguidas: bucle infinito de
redirección.
Error común:
Formatos de contenido
Para indicar los tipos de formato aceptados, el cliente debe especificar el
header Accept. La API RESTful debe devolver el resultado en el primer
formato disponible, o un error 406 si ninguno de los formatos aceptados
está disponible.
1. GET /people/1234
2. Accept: application/epub+zip, application/pdf, application/json
1. <Pedido>
2. <id>1234</id>
3. <status>Pending</status>
4. <links>
5. <link rel="factura">
6. http://example.com/api/pedido/1234/factura
7. </link>
8. </links>
9. </pedido>
1. Request:
2. GET /pedido/1234
3. Accept: application/hal+json, text/xml
4.
5. Response:
6. Status Code 200
7. Content-Type: application/hal+json
8. Content:
9. {
10. id: 1234,
11. status: 'Pending',
12. _links: {
13. factura: {
14. href: 'http://example.com/api/pedido/1234/factura',
15. type: 'application/pdf'
16. }
17. }
18. }
¿Para qué sirve Hypermedia? Para automatizar la utilización de APIs sin
que haya interacción humana. También para no tener que conocer la
ubicación exacta de todos los recursos.
Versionado de la API
https://api.twitter.com/1.1/statuses/user_timeline.json
http://gdata.youtube.com/feeds/api/videos?
q=surfing&caption&v=2
Nuestro servidor puede, por ejemplo, separar con un proxy las peticiones de
cada versión a una máquina o endpoint diferente.
1. var people = [
2. {dni: 111, name: 'Pepe', age: 30},
3. {dni: 222, name: 'Jose', age: 20},
4. {dni: 333, name: 'Carlos', age: 25}
5. ];
GET /people
GET /people/<dni>
POST /people/<dni>
PUT /people/<dni>
DELETE /people/<dni>
Express (http://expressjs.com/)
Inspirado en Sinatra (http://es.wikipedia.org/wiki/Sinatra_%28software%29),
un popular framework de aplicaciones web para Ruby. Del mismo modo que
Sinatra, en lugar de seguir el popular patrón MVC se centra en permitir la
creación de aplicaciones web con el mínimo esfuerzo.
Restify (http://mcavage.me/node-restify/)
A diferencia de Express, que está diseñado para construir aplicaciones web
y añade soporte para renderizado de vistas, Restify es un framework
diseñado para crear servicios REST, exclusivamente. De esta forma es más
ligero que Express. El código escrito para Restify es prácticamente
idéntico al escrito para Express, pero Restify ofrece algunas facilidades
muy útiles para nuestras APIs:
Koa (http://koajs.com/)
Se trata de una evolución de Express, basada en el uso global de
generadores (https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Statements/function%2a). Al contrario
que Express, no incorpora ningún middleware de serie. Esto quiere decir
que los objetos request y response originales del módulo http de
Node.js no se alteran, sino que se trabaja con un objeto auxiliar por petición:
el "contexto":
1. app.use(function *(){
2. this; // is the Context
3. this.request; // is a koa Request
4. this.response; // is a koa Response
5. this.req; // original http request
6. this.res; // original http response
7. });
Sails (http://sailsjs.org/)
Se trata de un framework MVC modular que utiliza Express por debajo para
gestionar la comunicación HTTP. Automatiza la creación de APIs de forma
importante:
Hapi.js (http://hapijs.com/)
Sigue un enfoque parecido al de Express, centrándose en facilitar la
construcción de servicios web en lugar de preocuparse por la
infraestructura de la aplicación. Tiene una forma propia de especificar rutas
y manejadores:
Basic authentication
1. HEADERS: {
2. "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
3. ...
4. }
1. "http://esto_es_mi_api.com/people?auth=292j293j98fkl2jl1kxc
v0"
Un posible problema es el robo de dicho token de acceso. Se pueden
realizar algunas mejoras para evitarlo:
OAuth 2.0:
1. #!/bin/bash
2.
3. curl -X GET -v 127.0.0.1:3000/people
4.
5. curl -X GET -v 127.0.0.1:3000/people/111
6.
7. curl -X POST -v -H "Content-Type: application/json" \
8. --data '{"dni": 444, "name": "Enrique", "age": 33}' 127.0.0.
1:3000/people/444
9.
10. curl -X PUT -v -H "Content-Type: application/json" \
11. --data '{"dni": 444, "name": "Jose", "age": 33}' 127.0.0.1:3
000/people/444
12.
13. curl -X DELETE -v 127.0.0.1:3000/people/111
Por ejemplo, la petición GET sobre el recurso /people/333 daría como
resultado:
También es posible ver las peticiones por segundo que aguanta para un
determinado número de clientes simultáneos:
Conclusiones
Un servicio o API tiene que cumplir 3 requisitos fundamentales para
ser considerado REST:
1. Uso correcto de URIs.
2. Uso correcto de HTTP.
Métodos HTTP
Códigos de estado
Formatos de contenido
3. Implementación de Hypermedia.
La mayoría de APIs que dicen ser REST en realidad no lo son.
Podemos probar cualquier API con CURL.
El rendimiento es importante, debemos probar nuestras APIs en
situaciones extremas.
Node.js es una buena plataforma para la construcción de APIs REST.
Existen diversos enfoques y módulos para construir APIs con Node.js.