👉 Ver todas las notas
- API
- REST
- CRUD
- API Key
- Endpoint
- Verbos HTTP
- HTTP Status Codes
path params
vsquery params
en una API REST- Ejercicio
Application Programming Interface), define una interfaz con ciertas operaciones, que nos permiten interactuar con una aplicaciĂłn hosteada en un servidor.
Nos permite agregar una barrera de seguridad: el cliente no puede acceder directamente a la DB sino a través de la API.
Una API expone datos y diferentes tipos de acciones que podemos realizar, a través de los endpoints, por ejemplo
- InformaciĂłn disponible
- Servicios
- Parámetros
- Formato de la respuesta
Una API forma parte del backend de una aplicaciĂłn y es independiente de los lenguajes y plataformas que utilicemos.
REST (Representational State Transfer) es una convenciĂłn para desarrollar servicios web (APIs), basados en el protocolo HTTP. Vamos a llamar APIs REST a las APIs que desarrollemos siguiendo estas convenciones.
- Utilizamos URLs para definir recursos
JSON
como formato de intercambio- Acciones basadas en los verbos HTTP (utilizamos el protocolo HTTP para transferir datos)
- Uso de los status HTTP (
200 - ok
,404 - resource not found
,500 - server error
, etc) - Stateless: los datos del cliente no se almacenan en el servidor entre requests. Cada request contiene toda la info necesaria para ser ejecutada, por lo que que ni el cliente ni el servidor necesitan recordar ningĂşn estado previo.
- Arquitectura cliente<->servidor: hay una separaciĂłn de responsabilidades entre el frontend (cliente) y el backend (server). Operan de forma independiente entre sĂ y ambos pueden ser reemplazados.
- Cache: la data que proviene del server puede ser cacheada en el cliente, lo cual nos permite obtener mejoras de performance.
- Sistema de capas: el cliente no necesita saber si está interactuando directamente con un servidor, proxy, load balancer, etc.
- Interfaz uniforme cada recurso del servicio REST debe tener una Ăşnica direcciĂłn, "URI", que simplifica la interacciĂłn entre el cliente y el servidor.
👉 Ver más detalles en Core Principles of RESTful API
Una API REST nos permite desarrollar servicios para crear, leer, actualizar o eliminar datos, conocidos como CRUD operations por sus siglas en inglés (Create, Read, Update, Delete).
Sirve para identificar al usuario/cliente que está realizando el request. Generalmente se utiliza para aplicar rate limiting (limitar los recursos del servidor que podemos consumir de forma gratuita, por ejemplo bloqueando los requests después de cierta cantidad).
Para más info, ver Use Web APIs.
Un endpoint de una API REST expone un recurso o una colección de recursos para que sean consumidos. Un endpoint incluye el tipo de acción (request) a realizar con el recurso (o la colección), la ruta y los parámetros necesarios. El tipo de acción está basado en los verbos HTTP (GET
, POST
, PUT
, DELETE
, etc). Por ejemplo
Los endpoints que definamos tienen que resolver el siguiente problema: proveer una forma uniforme de identificar los recursos disponibles (interfaz uniforme)
Request 1
GET /api/customers
Response 1
[
{ "id": 1, "name": ...},
{ "id": 2, "name": ...},
...
]
Request 2
GET /api/customers/7
Response 2
{ "id": 7, "name": ...}
Endpoints
GET /api/customers
GET /api/customers/7
POST /api/customers
PUT /api/customers/1
DELETE /api/customers/2
GET
: Leer data de un recurso existente, sin modificarlo.POST
: Crear un nuevo recurso en el server, usando la info enviada en el payload del request. Por convenciĂłn, cuando creamos un nuevo recurso, debemos retornar el objeto que lo representa en elresponse
.PUT
: Actualizar un recurso existente, usando la info enviada en el payload del request. En el caso de que el recurso no exista, lo crea.DELETE
: Eliminar un recurso existente.
Ver httpstatuses.com
Ver When do I use path params vs. query params in a RESTful API?
Vamos a crear una API REST con Express
. La misma tendrá informaciĂłn sobre pelĂculas, almacenada en un array.
El formato de las pelĂculas será el siguiente:
movie = {
"id": 1,
"title": "Back to the Future",
"year": 1985,
"genre": "Science Fiction"
}
- Acá hay ejemplos de pelĂculas para usar y acá tenĂ©s un JSON con muchas más.
- El array de pelĂculas estará inicialmente vacĂo. Se recomienda utilizar un mĂłdulo aparte para el array (importarlo donde sea necesario) y definirle una API para interactuar con el mismo (ejemplo, si el array se llama
movies
, definir la operaciĂłnmovies.add
para agregar una nueva pelĂcula, etc) - El
id
se calcula al agregar una nueva pelĂcula (no forma parte del payload del request), segĂşn el orden (la primera tendráid=1
, la segundaid=2
, etc). - Utilizar el
Router
deExpress
para definir la lĂłgica de routing en un mĂłdulo aparte, y setear/api
como prefijo de todas las rutas. Utilizar el métodoroute()
, para definir las rutas de una forma más declarativa. - Utilizar
nodemon
para desarrollar. - En caso de necesitar debuggear la aplicaciĂłn, utilizar esta guĂa.
GET /api/movies
: retorna el array de pelĂculas, en formatoJSON
.GET /api/movies/:id
: retorna la pelĂcula con elid
correspondiente, en formatoJSON
. En el caso de que no exista, generar el error"404 - The movie with the id {ID} was not found"
(donde ID es el parámetro utilizado) constatus code
404 y pasarle el objetoerr
anext
.POST /api/movies
: agrega una nueva pelĂcula, con la info especificada más arriba. Validar elbody
del request como se indica más abajo. Si es inválido, generar el error"400 - Bad Request"
y pasarle el objetoerr
anext
, sino, agregar la pelĂcula correspondiente y retornar la info de la misma en elresponse
.PUT /api/movies/:id
: actualiza la info de una pelĂcula (title
Ăłyear
, elid
no puede editarse). Para esto, primero debe buscarla por elid
y si no existe, debe agregar la nueva pelĂcula, con elid
correspondiente.DELETE /api/movies/:id
: elimina la pelĂcula con elid
correspondiente. Para esto, primero debe buscarla por elid
, si no existe, generar el error"404 - The movie with the id {ID} was not found"
(donde ID es el parámetro utilizado), y unstatus code
404 y pasarle el objetoerr
anext
.GET /api/movies/genres
: retorna la lista de gĂ©neros (sin repetir), correspondientes a las pelĂculas que tengamosGET /api/movies/years
: retorna la lista de años (sin repetir), correspondientes a las pelĂculas que tengamos
- Si se utiliza el query string
?year=
conGET /api/movies
, debe retornarse la lista de pelĂculas correspondientes a ese año, en formatoJSON
. - Si se utiliza el query string
?genre=
conGET /api/movies
, debe retornarse la lista de pelĂculas correspondientes a ese gĂ©nero, en formatoJSON
. - Si se utilizan los query strings
?sortBy=title
Ăł?sortBy=year
con el endpointGET /api/movies
, debe retornarse la lista de pelĂculas ordenada por año Ăł nombre de forma ascendente, respectivamente.
En ambos casos, si no hay pelĂculas para mostrar, debe retornarse el array vacĂo []
(siempre como JSON
).
Utilizar el middleware express-validator
para realizar las siguientes validaciones sobre el input (body
del request)
title
: debe existir y tener al menos 2 caracteres, sino generar el errormovie title is required and should have minimum 2 characters.
, constatus code
400 y pasarle el objetoerr
anext
.year
: debe ser un valor numérico entre 1800 y 2020, sino generar el errormovie year is required and should be a number between 1800 and 2020.
, constatus code
400 y pasarle el objetoerr
anext
.
Router
deExpress
- Error-handling middleware (ver detalles en helpful-express-middleware)
express-validator
, para realizar las validaciones correspondientesmorgan
, para loguear en la terminal todos los requests y responses generados