Última actualización
Última actualización
Es un desarrollado por Platanus que reúne un conjunto de gemas y configuraciones pensadas para construir APIs REST de calidad.
Por dos motivos:
Porque en esta gema hemos ido recopilando todas aquellas herramientas que consideramos nos han sido útiles a lo largo de nuestros desarrollos en Platanus.
Porque todas estas configuraciones varían muy poco (o nada) de proyecto en proyecto. Por esto, nos pareció buena idea realizar estas mejoras en un único lugar para luego ocupar en todas nuestras aplicaciones.
La gema viene instalada si el proyecto se generó usando con la opción api
activada. Si el proyecto no fue creado con Potassium, se puede instalar siguiendo las instrucciones de .
Supongamos que tenemos el modelo:
y queremos tener los típicos endpoints REST:
Para esto, deberíamos ejecutar el siguiente generador:
Tener en cuenta:
Siguiendo el ejemplo anterior, si corremos el generador, se agregará el siguiente serializer en /app/serializers/api/internal/blog_serializer.rb
Al ejecutar por ejemplo la request GET /api/internal/blogs
obtendremos algo así:
Tener en cuenta:
Siempre utiliza serializers para responder con el API. Es importante que todos los endpoints devuelvan la información con el mismo formato.
Supongamos que tenemos el siguiente controller con el create
endpoint y supongamos también que el atributo title
es requerido:
Tener en cuenta:
Siempre lanza exceptions y deja que el concern los maneje. No hagas condicionales ni devuelvas errores custom. Los errores siempre deberían tener el mismo formato y ser manejados en un único lugar (el concern).
Si necesitas manejar algún tipo de error específico, siempre podrás agregarlo así:
Siguiendo el ejemplo anterior:
Al ejecutar POST /api/internal/blogs
, el método respond_with
invocará al responder y entregará el objeto Blog
que se acaba de crear usando el serializer y, por tratarse de un POST
, entenderá que debe devolver el HTTP status code 201 (created).
El responder además devolverá:
Un HTTP status code 200 OK si se trata de un GET
o un PUT
además del/los recurso/s serializado/s con AMS.
Un HTTP status code 204 No Content si se trata de un DELETE
.
Tener en cuenta:
Evitar usar render
. El uso de render
se salta el responder y nos obliga a especificar el código y recurso a devolver en el mismo controller. Esto es una mala práctica porque es algo que debería definirse en un único lugar y ser consistente a través de todos los controladores.
Si usamos el generador rails g power_api:controller blog
, se crearán dentro del directorio: spec/requests/api/internal/blogs_spec.rb
los tests para nuestro controlador.
Para activarla simplemente debemos ejecutar el método paginate
así:
Para ver el recurso paginado se deberá ejecutar la request así:
Esto agregará:
Headers relacionados con la paginación.
Links a self
, first
, prev
, next
y last
en el serializer.
Para activarlo simplemente debemos ejecutar el método filtered_collection
así:
Para filtrar la información se deberá ejecutar la request así:
El modo internal se utiliza cuando la API va a ser consumida por un cliente front que comparte sesión con la API. En cambio, la API modo exposed está pensada para ser usada por clientes que están servidos en otro lado. Las principales diferencias son que:
En modo internal no hay versiones. Se entiende que la API tendrá un único cliente entonces no tiene sentido versionar. Por esto en modo internal verás controllers como: Api::Internal::BlogsController
y en exposed: Api::V1::BlogsController
, Api::V2::BlogsController
, etc.
ℹ️ Es importante saber que se puede tener en un mismo proyecto una api internal y exposed.
Para ver el funcionamiento, puedes visitar el README de la gema pero en corto lo que hacemos es lo siguiente:
Corriendo el generador de la gema, crearemos una migración que agregará un authentication_token
al modelo que queremos autorizar.
Ejecutaremos en el modelo a autorizar el método acts_as_token_authenticatable
así:
Luego en el controller que queremos que sea autorizado ejecutaremos acts_as_token_authentication_handler_for
así:
Esto exigirá que las requests sean firmadas con email y token
Ejecutaremos la request así: GET <http://localhost:3000/api/v1/blogs/1?user_email=developer@platan.us?user_token=xxx
>
Tener en cuenta:
Podemos correr el instalador de Power API así:
para que deje lista la configuración de Simple Token Authentication
Por defecto el token se manda por query string, quizás sería bueno cambiar la configuración de Simple Token Authentication para que se mande por header.
La gema no viene con un endpoint que permita conseguir el token del usuario. Por esto, es buena idea crear a mano un controller login_attempts_controller.rb
con un action create
que devuelva el token para un email
y password
.
Esto creará el controlador (dentro de /app/controllers/api/internal/blogs_controller.rb
) y todo lo necesario para que tengas tus endpoints funcionando. Para más información u opciones que permite el comando, revisa la
El generador sirve para crear los endpoints REST típicos y . Si necesitas algo custom, deberás hacerlo a mano. Pero siempre ten en cuenta que si piensas en recursos REST, probablemente encontrarás una forma de modelar que calce con lo que ofrece el generador.
Al ejecutar la request POST /api/internal/blogs
sin enviar el atributo title
, se lanzará una exception que será manejada por el devolviendo una respuesta con formato estándar:
Para más opciones de filtrado revisa
En modo internal se usa para autenticar los recursos. En cambio en el modo exposed se usa (que se instala sobre devise)
(Está un poco desactualizado el ejemplo pero el espíritu es el mismo)