Creación de una API
Qué es una API
- Es una forma de describir la forma en que los programas o los sitios webs intercambian datos.
- El formato de intercambio de datos normalmente es JSON o XML.
¿Para qué necesitamos una API?
- Ofrecer datos a aplicaciones que se ejecutan en un movil
- Ofrecer datos a otros desarrolladores con un formato más o menos estándar.
- Ofrecer datos a nuestra propia web/aplicación
- Consumir datos de otras aplicaciones o sitios Web
Provedores de APIs
- Algunos ejemplos de sitios web que proveen de APIS son:
- Twitter: acceso a datos de usuarios, estado
- Google: por ejemplo para consumir un mapa de Google
- Pero hay muchos más: Facebook, YouTube, Amazon, foursquare...
- Pero todavía hay muchos más: directorio de proveedores de APIs
Qué significa API REST
- REST viene de, REpresentational State Transfer
- Es un tipo de arquitectura de desarrollo web que se apoya totalmente en el estándar HTTP.
- REST se compone de una lista de reglas que se deben cumplir en el diseño de la arquitectura de una API.
- Hablaremos de servicios web restful si cumplen la arquitectura REST.
- Restful = adjetivo, Rest = Nombre
Como funciona REST
Llamadas al API
GET http://www.formandome.es/api/cursos/1
- El código de estado HTTP representa el resultado:
200 OK HTTP/1.1
404 NOT FOUND HTTP/1.1
Creación de recursos
- La URL estará “abierta” (el recurso todavía no existe y por tanto no tiene id)
- El método debe ser POST
http://eventos.com/api/eventos/3/comentarios
Respuesta a la creación de recursos
- Resultados posibles:
- 403 (Acceso prohibido)
- 400 (petición incorrecta, p.ej. falta un campo o su valor no es válido)
- 500 (Error del lado del servidor al intentar crear el recurso, p.ej. se ha caído la BD)
- 201 (Recurso creado correctamente)
- ¿Qué URL tiene el recurso recién creado?
- La convención en REST es devolverla en la respuesta como valor de la cabecera HTTP Location
Actualización de recursos
- Método PUT
- Según la ortodoxia REST, actualizar significaría cambiar TODOS los datos
- PATCH es un nuevo método estándar HTTP (2010) pensado para cambiar solo ciertos datos. Muchos frameworks de programación REST todavía no lo soportan
- Resultados posibles
- Errores ya vistos con POST
- 201 (Recurso creado, cuando le pasamos el id deseado al servidor)
- 200 (Recurso modificado correctamente)
Eliminar recursos
- Método DELETE
- Algunos resultados posibles:
- 200 OK
- 404 Not found
- 500 Server error
- Tras ejecutar el DELETE con éxito, las siguientes peticiones GET a la URL del recurso deberían devolver 404
Arquitectura REST
Reglas de una arquitectura REST
- Interfaz uniforme
- Peticiones sin estado
- Cacheable
- Separación de cliente y servidor
- Sistema de Capas
- Código bajo demanda (opcional)
- La interfaz de basa en recursos (por ejemplo el recurso Empleado (Id, Nombre, Apellido, Puesto, Sueldo)
- El servidor mandará los datos (vía html, json, xml...) pero lo que tenga en su interior (BBDD por ejemplo) para el cliente es transparente
- La representación del recurso que le llega al cliente, será suficiente para poder cambiar/borrar el recurso:
- Suponiendo que tenga permisos
- Por eso en el recurso solicitado se suele enviar un parámetro Id
- Mensajes descriptivos:
- Usar las características del protocolo http para mejorar la semántica:
- HTTP Verbs
- HTTP Status Codes
- HTTP Authentication
- Procurar una API sencilla y jerárquica y con ciertas reglas: uso de nombres en plural
Peticiones sin estado
- http es un protocolo sin estado ---> mayor rendimiento
GET mi_url/empleados/1234
DELETE mi_url/empleados/1234
- En la segunda petición hemos tenido que incidar el identificador del recurso que queremos borrar
- El servidor no guardaba los datos de la consulta previa que tenía el cliente en partícular.
- Una petición del tipo DELETE mi_url/empleado debe dar error, ¡falta el id y el servidor no lo conoce!
Cacheable
- En la web los clientes pueden cachear las respuestas del servidor
- Las respuestas se deben marcar de forma implícita o explícita como cacheables o no.
- En futuras peticiones, el cliente sabrá si puede reutilizar o no los datos que ya ha obtenido.
- Si ahorramos peticiones, mejoraremos la escabilidad de la aplicación y el rendimiento en cliente (evitamos principalmente la latencia).
Separación de cliente y servidor
- El cliente y servidor están separados, su unión es mediante la interfaz uniforme
- Los desarrollos en frontend y backend se hacen por separado, teniendo en cuenta la API.
- Mientras la interfaz no cambie, podremos cambiar el cliente o el servidor sin problemas.
Sistema de capas
- El cliente puede estar conectado mediante la interfaz al servidor o a un intermediario, para el es irrelevante y desconocido.
- Al cliente solo le preocupa que la API REST funcione como debe: no importa el COMO sino el QUE
- El uso de capas o servidores intermedios puede servir para aumentar la escalabilidad (sistemas de balanceo de carga, cachés) o para implementar políticas de seguridad
Código bajo demanda (opcional)
- Los servidores pueden ser capaces de aumentar o definir cierta funcionalidad en el cliente transfiriéndole cierta lógica que pueda ejecutar:
- Componentes compilados como applets de Java
- JavaScript en cliente.
Consejos para elaborar una API REST
Versiones del API
- Los cambios en el código no deberían afectar al API
- Si hay cambios en el API se deben usar versiones para no fustrar a los desarrolladores
- La mejor opción es añadir un prefijo a las URLS:
GET /v1/geocode HTTP/1.1
Host: api.geocod.io
GET /v2/geocode HTTP/1.1
Host: api.geocod.io
HTTP verbs
- Si realizamos CRUD, debemos utilizar los HTTP verbs de forma adecuada para cuidar la semántica.
- GET: Obtener datos. Ej: GET /v1/empleados/1234
- PUT: Actualizar datos. Ej: PUT /v1/empleados/1234
- POST: Crear un nuevo recurso. Ej: POST /v1/empleados
- DELETE: Borrar el recurso. Ej: DELETE /v1/empleados/1234
- ¿PATCH?: Para actualizar ciertos datos
Nombre de los recursos
- Plural mejor que singular, para lograr uniformidad:
- Obtenemos un listado de clientes: GET /v1/clientes
- Obtenemos un cliente en partícular: GET /v1/clientes/1234
- Url's lo más cortas posibles
- Evita guiones y guiones bajos
- Deben ser semánticas para el cliente
- Utiliza nombres y no verbos
- Estructura jerárquica para indicar la estructura: /v1/clientes/1234/pedidos/203
Códigos de estado
- Se utilizan los códigos de estado de http
- Si realizamos un request de POST deberemos devolver un 201.
- Se pueden producir múltiples errores en la llamada al API:
- falta de permisos
- errores de validación
- O incluso un error interno de servidor.
- Siempre se debe devolver un código de estado HTTP con los requests.
- Añadir un mensaje de error si es necesario.
- En función de la petición nuestra API podría devolver uno u otro formato.
- Nos fijaremos en el ACCEPT HEADER
GET /v1/geocode HTTP/1.1
Host: api.geocod.io
Accept: application/json
*GET /v1/geocode HTTP/1.1
Host: api.geocod.io
Accept: application/xml
- En principio utilizaremos JSON: sencillo y simple
- XML no es nuestro amigo: schemas, namespaces...
- Si no es un requerimiento, evitaremos XML
Solicitudes AJAX entre dominios
Problemática
- El modelo de seguridad de las aplicaciones web no permite en principio realizar peticiones Ajax entre dominios
- En general esto es OK, a nadie le gustaría que código malicioso de una URL estuviera accediendo a ningún dato de la solapa del navegador que está abierta con nuestra cuenta bancaria
- Pero también es un problema, por ejemplo con AJAX: una página de http://localhost en principio no puede hacer una petición AJAX a Google
- Como consecuencia, se han tenido que idear diversos “trucos”/técnicas para intentar sobrepasar este límite
Técnicas para evitar las restricciones de seguridad
- Lo más habitual es el uso de JSONP (JSON con Padding)
- Se basa en que aunque no podemos consumir datos de otro dominio vía XHR, si podemos cargar un script de dicho dominio
CORS
- En el 2008 se publicó la primera versión de la especificación XMLHttpRequest Level 2.
- CORS es el acrónimo de Cross-origin resource sharing.
- Debemos tener presente, que los navegadores antiguos no soportan CORS.
- Esta nueva especificación, añade funcionalidades nuevas a las peticiones AJAX como las peticiones entre dominios (cross-site), eventos de progreso y envio de datos binarios.
- CORS requiere configuraciones en el servidor.
Autenticación y validación en API REST
Métodos de autenticación
- Básicamente tenemos dos formas de implementar la autenticación en servidor:
- Basada en cookies, la más utilizada:
- El servidor guarda la cookie para autenticar al usuario en cada request.
- Habrá que tener un almacen de sesiones: en bbdd, Redis...
- **Basada en tokens**, se confía en un token firmado que se envía al servidor en cada petición
¿Qué es un token?
-
- Normalmente se consigue después de hacer login mediante usuario/contraseña
-
- Normalmente un hash calculado con algún dato (p.ej. login del usuario + clave secreta)
- Además el token puede llevar datos adicionales como el login
- ¿Cómo comprueba el servidor que es válido?
- Generando de nuevo el Hash y comprobando si es igual que el que envía el usuario (100% stateless)
- O bien habiendo almacenado el Hash en una B.D. asociado al usuario y simplemente comprobando que coincide
Beneficios de usar tokens
- Uso entre dominios
- cookies + CORS no se llevan bien
OAuth
- Para que una app pueda acceder a servicios de terceros sin que el usuario tenga que darle a la app sus credenciales del servicio
- Ejemplo: una app que permite publicar en tu muro de FB, pero en la que no confías lo suficiente como para meter tu login y password de FB
- Es el estándar en APIs REST abiertos a terceros
- Se basa en el uso de un token de sesión
Terminología de OAuth
- En un proceso AUTH intervienen 3 actores:
- Consumer: El servicio al que el usuario quiere acceder usando una cuenta externa.
- Service Provider: Al servicio de autenticación externo se le llama Service Provider.
- El usuario final
Flujo en OAuth
- El consumer pide un token al service provider, esto es transparente para el usuario.
- El consumer redirige al usuario a una página segura en el service provider, pasándole el token como parámetro.
- El usuario se autentica en la página del service provider, validando el token.
- El service provider envía al usuario de vuelta a la página del consumer especificada en el parámetro oauth_callback.
- El consumer recoge al usuario en la callback URL junto con el token de confirmación de identidad.
Arquitecto especialista en gestion de proyectos si necesitas desarrollar algun proyecto en Bogota contactame en el 3006825874 o visita mi pagina en www.arquitectobogota.tk