spinner

Replica tu backend en front con Ember CLI Mirage

Ember.js es un framework para construir grandes aplicaciones web, y su ecosistema de addons es ideal a la hora de reutilizar código y ampliar las funcionalidades del framework. En este artículo veremos en profundidad por qué Ember CLI Mirage es uno de los addons más utilizados, y cómo nos facilita nuestra tarea diaria.

La mayoría de aplicaciones web necesitan realizar llamadas a un servidor para recibir los datos que va a presentar al usuario. Cuando estamos construyendo la aplicación, la tendencia habitual es tener el servidor funcionando e ir haciendo peticiones desde el frontal, o bien «engañar» a nuestro frontal para que maneje datos estáticos de prueba. Esta última alternativa es la que necesitaremos obligatoriamente a la hora de testear la aplicación.

Pero, ¿no resultaría más cómodo no tener que montar todo backend en nuestra máquina local o hacer peticiones a uno remoto?. La alternativa es utilizar mocks, y para ello en Ember.js contamos con el addon Ember CLI Mirage, con el que podemos construir una copia de los servicios remotos, con factorías de datos y personalización total de las llamadas y respuestas HTTP.

Configuración

Mirage está activado por defecto en los entornos de development y test. Si preferimos desactivarlo en algún entorno y utilizar el backend remoto, podemos hacerlo en el fichero config/environment.js):

 // config/environment.js
 ...
 if (environment === 'development') {
 ENV['ember-cli-mirage'] = {
 enabled: false
 };
 }

En el fichero mirage/config.js se configuran los endpoints que Mirage debe interceptar. Por defecto, si se hace una petición a un endpoint que no esté definido en Mirage, se lanzará un error. Este comportamiento puede modificarse con la función passthrough():

// mirage/config.js
 this.passthrough();

Esto hará que Mirage deje pasar las llamadas a endpoints que desconoce, e intercepte sólo los que tiene definidos.

ember-cli-mirage

Funcionamiento básico

Para ver la siguiente documentación en práctica, es recomendable leer el artículo Mocking a Blog Backend with Mirage and JSON API.
Para endpoints sencillos, podemos especificar directamente qué respuesta queremos que genere Mirage:

// mirage/config.js
 this.get('/posts', () => {
 return {
 data: [
 { id: 1, type: 'posts', attributes: { title: 'Post 1' } },
 { id: 2, type: 'posts', attributes: { title: 'Post 2' } },
 { id: 3, type: 'posts', attributes: { tiele: 'Post 3' } },
 ]
 };
 });

Cada vez que la aplicación haga una llamada GET a /posts, Mirage responderá con este objeto de datos.

Datos dinámicos

Obviamente, los datos hardcoded se nos quedarán cortos para la mayoría de nuestras necesidades. La solución es generar modelos y datos dinámicos.
Creamos un modelo para Mirage:

 $ ember g mirage-model post
 Ahora configuramos el endpoint dinámico para que utilice la base de datos de Mirage:
 // mirage/config.js
 this.get('/posts', (schema, request) => {
 return schema.posts.all();
 });

// o simplemente, haciendo uso del standard:
 this.get('/posts');

Pero la base de datos de Mirage aún está vacía, por lo que este endpoint nos devolverá un array vacío. Veamos cómo llenarla de información.

Generando datos de prueba

Mirage utiliza Factories para crear mocks de modelos. Así podemos generar automáticamente datos de prueba para nuestros modelos, en lugar de tener que definirlos a mano. Como ayuda, utilizamos la librería Faker.js.

Vamos a crear un factory para nuestro modelo Posts:

ember g mirage-factory post
 Ahora podemos definir de qué manera se generarán los datos para cada propiedad del modelo:
 // mirage/factories/post.js
 import { Factory } from 'ember-cli-mirage';
 import faker from 'faker';

export default Factory.extend({
 title(i) {
 return `Post ${i} ${faker.lorem.sentence()}`;
 },

image(i) {
 return `image-${i}`; // image-1, image-2, etc.
 },

description() {
 return faker.lorem.paragraph();
 },
 });

Por último, llenamos nuestra base de datos con las funciones server.create (para 1 elemento) o server.createList (para un conjunto de elementos):

// mirage/scenarios/default.js
 export default function(server) {
 server.createList('post', 10);
 };

Ya tenemos nuestro modelo, cómo generar sus datos (factory) y la DB de Mirage llena de información. Ahora, nuestro fake-endpoint /posts devolverá un conjunto de Posts con datos aleatorios que cumplen con las mismas reglas que el backend real.

NOTA: en los tests de aceptación, Mirage ignora el fichero scenarios/default.js. De esta forma comenzamos cada test con un entorno limpio, en el que podemos crear los modelos que necesitemos para cada test (igual que antes, con create() o createList()). Después de cada test, el servidor de Mirage se reinicializa, por lo que el estado final de los datos de un test nunca influirá en el siguiente.

Traits

A veces necesitamos especificar ciertas características del modelo que necesitamos. Por ejemplo, podemos necesitar todos los datos de un Post, pero que además ésta haya sido archivado. Aquí intervienen los Traits:

// mirage/factories/post.js
 import { Factory, trait } from 'ember-cli-mirage';

export default Factory.extend({
 title(i) {
 return `Post ${i} ${faker.lorem.sentence()}`;
 },

...

archived: trait({
 archivedAt() {
 return faker.date.past();
 }
 })
 });

Con este trait llamado archived, sobreescribimos el valor de la propiedad archivedAt (que por defecto no estaba definida) para que devuelva una fecha pasada, es decir, un Post archivado. La forma de seleccionar este trait es muy simple:

server.create('post', 'expired'); // devuelve 1 post archivado
 server.createList('post', 3, 'expired'); // devuelve un array de 3 posts archivados

Relaciones entre modelos

Mirage también nos permite configurar relaciones entre modelos. Por ejemplo, si queremos añadir comentarios a nuestros posts (relación Post -> hasMany -> Activity):

Especificamos el tipo de relación en el modelo Mirage:

// mirage/models/post.js
 import { Model, hasMany } from 'ember-cli-mirage';

export default Model.extend({
 comments: hasMany(),
 });

Le decimos al factory que queremos comments en los posts:

// mirage/factories/post.js
 export default Factory.extend({
 ...
 afterCreate(post, server) {
 server.createList('comment', 5, { post });
 }
 });

Con todo lo anterior, ya estamos listos para aprovechar toda la potencia de Ember CLI Mirage. Os animamos a consultar la documentación oficial, donde descubriréis todos los detalles para exprimir este addon al máximo.

Como veis, generar datos de prueba de forma dinámica es extremadamente sencillo y, sin duda, merece la pena añadirlo a nuestra aplicación al inicio del desarrollo. Si utilizáis otros frameworks, sin duda este será uno de los addons que más echaréis de menos de Ember.js.

¿Quieres saber que más cosas hacemos en BBVA Next Technologies?

Utilizamos cookies propias y de terceros para mejorar nuestros servicios, brindarle una grata experiencia y mostrar a los usuarios publicidad relacionada con sus preferencias mediante el análisis de sus hábitos de navegación. Si continúa navegando por este sitio web, consideramos que acepta su uso. Puede cambiar la configuración u obtener más información accediendo a nuestra política de cookies aquí.