Criação de uma API Mocking com MirageJS

Neste artigo, iremos abordar um recurso que todo Dev Front-end gostaria de ter disponível desde o começo do desenvolvimento de uma aplicação Front- end: uma API Mocking para fazer a integração dos dados.

[adrotate banner=”4″]

Como todo início do desenvolvimento de uma aplicação web completa (back-end e frontend) nem sempre alguma destas partes estará disponível com antecedência para fazer a integração. Assim, é bastante comum em alguns projetos começarem o desenvolvimento pelo front-end (principalmente em casos onde você estará trabalhando sozinho no projeto), ou os dois ao mesmo tempo.

Dessa forma, como produtividade é muito importante, a equipe de front-end não quer ficar parada. Assim, pode seguir com a implementação com dados estáticos através de arquivos JSON ou armazenado em uma variável até que o back-end comece a fornecer uma API com dados reais que o front-end precise.

 

Vantagens e Desvantagens da API Mocking

A desvantagem de usar dados estáticos é que pode dificultar um pouco em apresentar cenários de dados. Por exemplo: em um momento podemos ter uma lista de usuários vazia, com 10, com 100, com 1000 e assim por diante e ficar alterando esses valores estaticamente não traz um dinamismo esperado.

A vantagem de utilizar uma API Mocking é que conseguiremos apresentar cenários de forma muito fácil, preparar o formato dos objetos (JSON) com as propriedades esperadas pelo front-end. Assim, o back-end pode reaproveitar e utilizar na criação da API, trazendo agilidade no desenvolvimento. Isso porque ele já saberá como front-end espera que os dados sejam enviados, testar solicitações HTTP (GET, POST, DELETE, PUT e PATCH) e apresentar mensagens de sucesso ou erros destas solicitações.

O que é o MirageJS?

Segundo a própria definição da documentação: “O Mirage JS é uma biblioteca de simulação de API que permite criar, testar e compartilhar um aplicativo JavaScript completo e funcional sem precisar depender de nenhum serviço de back-end”.

Ou seja, o MirageJS é uma lib que cria um servidor local dentro do projeto front-end que irá interceptar as requisições que saem da aplicação front-end e responde com o conteúdo que foi configurado.

Vantagens de utilizar o MirageJS

  • Servidor local dentro do próprio projeto. Isso significa que, assim que o servidor de desenvolvimento da aplicação front-end subir, o MirageJS (e o servidor local) irá executar junto;
  • Hot Reload: alterações ou adições de novos recursos. Ao salvar, o servidor automaticamente será atualizado e as mudanças serão refletidas na aplicação rodando no navegador;
  • Debugar é muito fácil. Como o MirageJS é totalmente construído com Javascript, podemos utilizar a instrução debugger e analisar o ponto especificado pelo o dev-tools do navegador;
  • Um mesmo servidor tanto para ambiente de desenvolvimento quanto para ambiente de testes;
  • Rotas para lidar com solicitações HTTP;
  • Um banco de dados e modelos para armazenar dados e definir relacionamentos;
  • ORM embutido;
  • Utilização de factories e seeds.

Iniciando um projeto React e configurando o servidor do MirageJS

Sem mais delongas, primeiro vamos implementar uma aplicação simples para registrar e remover usuários, e também enviar requisições HTTP para o servidor local do MirageJS.

Então, primeiro vamos iniciar um projeto React com ViteJS (https://vitejs.dev/guide/#scaffolding-your-first-vite-project). Você pode fazer isso rodando algum dos comandos abaixo:

npm create vite@latest miragejs-demo
// or
yarn create vite miragejs-demo

Para facilitar o entendimento do código, iremos utilizar o React sem Typescript. Entretanto, se você estiver confortável com o TS, fique a vontade para utilizar e fazer as devidas tipagens.

No App.jsx, vamos montar uma estrutura básica com um formulário simples para registrarmos o nome do usuário e listagem.

import { useState } from "react";
function App() {
const [users, setUsers] = useState([]);
return (
<div>
<form>
<p>
<label htmlFor="user-register">Name: </label>
<input
type="text"
id="user-register"
placeholder="Enter username"
name="userName"
/>
</p>
<button type="submit">Register</button>
</form>
<h1>Users:</h1>
<ul>
{(!!users || users.length > 0) &&
users.map((user, index) => <li key={index}>{user.name}</li>)}
</ul>
</div>
);
}
export default App;
Criação de uma API Mocking com MirageJS Luby Software

Como podemos notar, nossa aplicação inicia com dados de usuários vazio no estado. Dessa forma, para termos algo apresentado em tela inicialmente, iremos criar o servidor do MirageJS e definir a primeira rota GET, que vai retornar alguns usuários para o front-end.

Antes de mais nada, precisamos instalar o MirageJS em nossa aplicação:

# Using Yarn
yarn add -D miragejs
# Using npm
npm install --save-dev miragejs

No main.jsx, vamos criar o servidor com uma rota do tipo GET /users. Então, quando o nosso front-end fizer uma solicitação GET para /api/users, o Mirage responderá com esses dados:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { createServer } from "miragejs";
import "./index.css";
// Servidor local do MirageJS
createServer({
routes() {
this.namespace = "api";
this.get("/users", () => {
return {
users: [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" },
{ id: 3, name: "Gabe" },
],
};
});
},
});
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);

Ótimo! Agora, o próximo passo é fazer o front-end enviar uma solicitação para buscar os dados dos usuários:

function App() {
const [isLoading, setIsLoading] = useState(true)
const [users, setUsers] = useState([])
useEffect(() => {
async function fetchUsers () {
const res = await fetch('http://localhost:3000/api/users')
const data = await res.json()
setUsers(data.users)
setIsLoading(false)
}
fetchUsers()
}, [])
if (isLoading) {
return <p>Loading...</p>
}
return (
//... restante do código aqui.
)

E voilà! Assim, nosso front-end agora inicia com informações vindas de uma API funcional.

Criação de uma API Mocking com MirageJS Luby Software

Ao abrir o console do dev-tools do seu navegador, você conseguirá analisar o request e response interceptado pelo o MirageJS:

Criação de uma API Mocking com MirageJS Luby Software

Criando models, seeds e rotas para registrar e deletar usuários

Bom, até aqui nossa aplicação já possui uma configuração inicial de uma API Mocking. Apesar de termos um servidor devolvendo informações, o cenário atual ainda é de dados estáticos, já que preenchemos objetos de forma fixa (hardcode) no retorno da rota /api/users e o nosso desejo é de ter algo dinâmico.

Dessa forma, vamos fazer uso da camada de dados do Mirage que vai nos ajudar a escrever uma implementação de servidor mais poderosa.

Primeiro, vamos criar uma model para os users:

createServer({
models: {
user: Model
},
//... restante do código aqui.
)}

Agora, vamos refatorar nossa rota /users para torna-la dinâmica e fazer uso do banco de dados em memoria do Mirage:

// ...restante do código aqui
routes() {
this.namespace = "api";
this.get("/users", (schema, request) => {
return schema.users.all();
}
});

É através do schema que a rota acessará a model user e responderá com todas as informações do banco de dados do Mirage, no momento da solicitação. Assim, se voltamos ao nosso app rodando no navegador, teremos aquele cenário com o estado inicialmente vazio.

Sem problemas! Com seeds, podemos iniciar nosso banco de dados com alguns dados iniciais:

createServer({
//... restante do código aqui
seeds(server) {
server.create("user", { name: "John Doe" });
server.create("user", { name: "Jane Doe" });
server.create("user", { name: "Gabe" });
},
});

Maravilha! Voltamos ao cenário onde temos uma listagem de usuários sendo apresentada em tela. Agora chegou o momento de registrarmos usuários!

Para começar, vamos definir nossa rota do tipo POST para criar/registrar um usuário no banco de dados do Mirage:

createServer({
//... restante do código aqui
routes() {
//... restante do código aqui
this.post("/users", (schema, request) => {
const user = JSON.parse(request.requestBody);
return schema.users.create(user);
});
},
//... restante do código aqui
});

Então, o próximo passo é enviar os dados do usuário do front-end para o servidor:

function App() {
//... restante do código aqui
async function handleSubmit(e) {
e.preventDefault();
setIsLoading(true);
const {
userName: { value: userName },
} = e.currentTarget;
const res = await fetch("https://localhost:3000/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: userName,
}),
});
const data = await res.json();
const registeredUser = data.user;
setUsers((state) => state.concat(registeredUser));
setIsLoading(false);
}
//... restante do código aqui
return (
<div>
<form onSubmit={handleSubmit}>{/* ... restante do código aqui */}</form>
</div>
);
}

Por isso, o que faremos a seguir é definir a rota para deletar usuários pelo o id enviado via params.

createServer({
//... restante do código aqui
routes() {
//... restante do código aqui
this.delete("/users/:id", (schema, request) => {
const id = request.params.id;
return schema.users.find(id).destroy();
});
},
//... restante do código aqui
});

Agora no App.jsx vamos definir uma função que irá enviar a solicitação para deletar o usuário com base no id:

async function handleDeleteUserById(id) {
setIsLoading(true);
const res = await fetch(`/api/users/${id}`, { method: "DELETE" });
if (res.ok) {
setUsers((state) => state.filter((item) => item.id !== id));
}
setIsLoading(false);
}

Ainda no App.jsx, vamos adicionar um button no JSX que irá disparar/executar a função handleDeleteUserById:

//... restante do código aqui.
<ul>
{(!!users || users.length > 0) &&
users.map((user) => (
<li key={user.id}>
{user.name}
<button onClick={() => handleDeleteUserById(user.id)}>Delete</button>
</li>
))}
</ul>

Agora temos uma configuração no servidor onde ele inicia com alguns dados e fará inserções e remoções de registros de forma dinâmica.

Conclusão

Essa foi uma breve e básica introdução sobre o MirageJS, mostrando seus recursos na prática com uma simples aplicação em React.

A ferramenta é muito mais do que foi mostrado aqui. O Mirage consegue criar uma API REST completa, uma camada de dados poderosa que facilita a manipulação dos dados no banco, seeds, factories, relacionamentos, ORM, testes, entre outros recursos.

Sugiro que visitem a documentação para aprenderem mais sobre a ferramenta, que será muito útil para o desenvolvimento de suas aplicações, principalmente para os devs front-end.

Autor: Gabriel Pinheiro da Silva.

[adrotate banner=”5″]

Rodrigo Gardin

Rodrigo Gardin

CTO da Luby

Gostou do conteúdo? Compartilhe

Últimos posts

Fique por dentro das últimas novidades do mundo da tecnologia com os conteúdos do nosso blog!

Acelere a Transformação Digital da sua Empresa

Basta preencher este formulário ou ligar para +55 11 3055 3404

Fale conosco​

Technology Intelligence

Luby - Latin America

Rua Amália de Noronha, nº 151, 3º Andar, Sala 303
Pinheiros, São Paulo – SP – Brasil
CEP: 05410-010

Luby - North America

1110 Brickell Avenue
Suite 310
Miami – FL
United States

AWS certifications - AWS Partner
AWS certifications - Solutions Architect
Azure logo - Certifications Luby
Google Cloud Partner logo, a symbol of Luby's certifications and recognitions collaboration with Google.
Copyright ©2024 Luby Software LLC. All rights reserved.
Rolar para cima