API con Laravel
Algunos enlaces interesantes:
Buenas prácticas para el diseño de una API
¿Qué es un Servicio Web?
De acuerdo a Wikipedia:
Un servicio web (en inglés, web service o web services) es una tecnología que utiliza un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones.
Se trata de que una aplicación web intercambie información con otra aplicación mediante el protocolo HTTP.
Durante bastante tiempo se usó XML y el estándar SOAP para esta finalidad.
Actualmente se usa JSON y el estándar de facto API REST
¿Qué es JSON?
JavaScript Object Notation
Es una sintáxis creada para codificar objetos en JavaScript
Su uso se ha extendido mucho como alternativa a XML por lo que se considera un formato independiente de dicho lenguaje.
¿Qué es un API?
Application Programming Interface, Interfaz de Programación de Aplicaciones.
Es decir una interfaz que permite crear aplicaciones que usan determinado recurso.
Una API web usar el protocolo HTTP para lograr dicho objetivo.
¿Qué es un API REST?
Es una API web que sigue determinado stándar de facto.
El intercambio de información se basa en el uso de HTTP.
Usa un protocolo cliente-servidor sin estado. No pueden usarse cookies para mantener el estado de la sesión.
Cacheable. Una respuesta puede definirse como cacheable para evitar peticiones recurrentes.
Hipermedia como motor del estado. A partir de una dirección principal pueden obtenerse enlaces a todos los recursos del servicio.
Se define un conjunto de operaciones: GET, POST, PUT, DELETE.
Las operaciones CRUD se pueden asimilar al anterior conjunto y a unas rutas determinadas:
Ruta
Verbo
Descripción
/studies
GET
Obtenemos todos los estudios
/studies
POST
Creamos un estudio
/studies/{id}
GET
Obtenemos un estudio
/studies/{id}
PUT
Modificamos un estudio
/studies/{id}
PATCH
Modificación parcial
/studies/{id}
DELETE
Borramos un estudio
Se pueden añadir otras rutas para complementar el acceso:
Podemos definir búsquedas por un campo:
Podemos definir búsquedas más complejas:
Podemos definir ordenaciones, en este caso descendente:
Y podemos reflejar las relaciones:
Utilizaremos Postman para testear nuestra API
Independiente de que hagamos tests por otro lado
Es una herramienta muy extendida
Comprobación API inicial
Vamos a crear una ruta inicial:
Abre Postman y prueba su funcionamiento.
El anterior ejemplo funciona pero es más correcto de la siguiente manera:
Definimos el código de estado Http
Los arrays ordenados se covierten en arrays JSON
Los arrays asociativos se convierten en objetos
Los objetos se convierten en objetos:
Códigos de estado:
200's usados para respuestas con éxito.
300's usados para redirecciones.
400's usados cuando hay algún problema con la petición.
500's usados cuando hay algún problema con el servidor.
Lista de códigos HTTP que se deberían utilizar en la API RESTful:
200 OK - Respuesta a un exitoso GET, PUT, PATCH o DELETE. Puede ser usado también para un POST que no resulta en una creación.
201 Created – [Creada] Respuesta a un POST que resulta en una creación. Debería ser combinado con un encabezado Location, apuntando a la ubicación del nuevo recurso.
204 No Content – [Sin Contenido] Respuesta a una petición exitosa que no devuelve un body (por ejemplo en una petición DELETE)
304 Not Modified – [No Modificada] Usado cuando el cacheo de encabezados HTTP está activo y el cliente puede usar datos cacheados.
400 Bad Request – [Petición Errónea] La petición está malformada, como por ejemplo, si el contenido no fue bien parseado. El error se debe mostrar también en el JSON de respuesta.
401 Unauthorized – [Desautorizada] No se ha podido autenticar al usuario. Sin credenciales o credenciales no válidas.
403 Forbidden – [Prohibida] Cuando la autenticación es exitosa pero el usuario no tiene permiso al recurso en cuestión.
404 Not Found – [No encontrada] Cuando un recurso se solicita un recurso no existente.
405 Method Not Allowed – [Método no permitido] Cuando un método HTTP que está siendo pedido no está permitido para el usuario autenticado.
409 Conflict - [Conflicto] Cuando hay algún conflicto al procesar una petición, por ejemplo en PATCH, POST o DELETE.
410 Gone – [Retirado] Indica que el recurso en ese endpoint ya no está disponible. Útil como una respuesta en blanco para viejas versiones de la API
415 Unsupported Media Type – [Tipo de contenido no soportado] Si el tipo de contenido que solicita la petición es incorrecto
422 Unprocessable Entity – [Entidad improcesable] Utilizada para errores de validación, o cuando por ejemplo faltan campos en una petición.
429 Too Many Requests – [Demasiadas peticiones] Cuando una petición es rechazada debido a la tasa límite .
500 – Internal Server Error – [Error Interno del servidor] Los desarrolladores de API NO deberían usar este código. En su lugar se debería loguear el fallo y no devolver respuesta.
CRUD de Estudios en API
Antes de empezar, prueba otras rutas y fuerza la página de error "No encontrado".
Obtenemos un error 404 html.
Mejor un error 404 limpio en JSON.
Debemos definir una ruta de fallback, o ruta por defecto si ninguna otra es la solicitada
Controlador y rutas
Vamos a necesitar un controlador para gestionar nuestro recurso.
Ojo, vamos separar los controladores API del resto:
Basta con incluir una ruta resource y añadir el modificador except:
Index
Show
Create
Update: PUT
Delete
Estamos repitiendo la comprobación de 404 una y otra vez.
Sería interesante crear un método para no repetir código de esta manera.
Autenticación: JWT
REST se define como sin estado. Esto implica la no utilización de cookies y por ende sesiones.
JSON Web Token es un estándar usado para este fin.
Cuando un usuario hace login recibe un token que debe guardar en su aplicación cliente.
En el resto de peticiones debe entregar ese token para ser identificado.
Para JWT vamos a usar la librería tymondesigns/jwt-auth
Veamos como usarla para:
Hacer login
Hacer logout
Registrar un usuario
...
Instalación
Instalar dependencias:
Tomar fichero de configuración y crear clave de cifrado
La clave de cifrado se guarda en .env. Deberemos repetirlo en cada instalación.
Debemos modificar el fichero config/auth.php. Apartado guards
Modificar el modelo User
Añadimos un "use" en la cabecera
Más abajo en la definición de clase, implements ...
Por último, añadimos estos métodos:
Rutas y controlador
Usaremos un controlador. Lo creamos:
Necesitamos unas rutas en api.php para los métodos de autenticación:
Métodos del controlador
Necesitamos añadir algunos "use":
DRY. Para enviar el token al cliente usaremos este método:
Veamos ahora los métodos:
El constructor con un middleware.
Register
Login
Logout
La información del usuario: me().
Refresh
Autorización
Autenticar es identificar al usuario:
En web usamos sesión y los controladores que nos brinda Laravel
En api acabamos de crear el controalador Api/AuthController
El middleware Auth nos permite limitar el acceso a una ruta a usuarios identificados.
Pero no nos permite un control de acceso más elaborado
Laravel ofrece varias soluciones para esto. Vamos a estudiar las políticas.
Una política es una clase guardada den app/Policies
Una política va siempre asociada a un modelo.
Su creación:
Registro
Una vez creada debemos registrarla en el array $policies en AuthServiceProvider
Si no hacemos esto siempre obtendremos un estado 403 No autorizado
Definir reglas
Cada tipo de acceso se asocia a una regla. Una regla será un método dentro de la política.
Por defecto las polítcas traen una colección de reglas/métodos.
Por ejemplo el método update lo podemos usar para actualizar un estudio. Sus argumentos deben ser el user y un objeto del modelo protegido (Study):
Otros métodos se asocian a la clase en vez de a un objeto (create, viewAny, ...). Observa, crear o ver todos los estudios hace referencia a la clase, no a un estudio concreto.
Autorización web.
Para autorizar basta con usar el método autorize() del controlador:
Ejemplo sobre una regla de clase:
Ejemplo sobre una regla de objeto
Autorización web en blade.
Podemos ocultar enlaces usando directivas específicas:
Modelos un poco más a fondo:
Setters o mutators
Nomenclatura:
Ejemplo:
Getters o accessors
Permiten modificar o formatear los datos según están recogidos en la base de datos.
Nomenclatura:
Ejemplo:
Podemos añadir campos calculados:
Podemos incluso hacer que esos campos se añadan cuando serializamos objetos (conversión a JSON).
Fechas
Las fechas se leen como texto de la base de datos
Laravel tiene una clase específica para tratar fechas y horas llamada Carbon
Podemos forzar que nuestras fechas hagan casting a esta clase cada vez que se leen de la BBDD.
Para hacerlo basta con definir la variable $dates:
Una vez hecho esto podemos usar dicho campo como una fecha:
Laravel como cliente Http
Una aplicación web también puede ser un cliente Http
Típicamente podemos hacer que una aplicación web consuma los recursos ofrecidos por una API Rest
Vamos a crear una nueva instalación de Laravel (laravel20client)
Vamos a crear un controlador StudyController que consuma los recursos de la API que ya hemos creado.
Por simplificar, vamos a prescindier de autenticación y autorización
Ruta api:
Código del controlador en la API
Crearmos un nuevo proyecto laravel20client
Añadimos un controlador StudioController que va a gestionar los estudios de nuestra API (en español por diferenciar):
Ahora se trata de añadir rutas y métodos a este controlador para completar el CRUD a través de nuestra API
Index
Show
Store
Update
Delete
Index
Last updated
Was this helpful?