Freqüentemente, ao construir aplicativos que fazem interface com um back-end, você precisa esperar que os dados ativos estejam disponíveis no back-end para continuar o desenvolvimento. Isso pode resultar em produtividade reduzida e tempos de resposta lentos. As APIs de simulação permitem que você crie o front-end do seu aplicativo sem ter que depender dos dados do back-end.

Neste tutorial do Mirage JS , mostraremos como construir uma API simulada. Abordaremos o seguinte em detalhes:

Para acompanhar este tutorial, você deve ter:

O que é Mirage JS?

Mirage JS é uma biblioteca JavaScript que permite simular APIs que podem ser usadas para construir, testar e compartilhar um aplicativo JavaScript full-stack. O que torna o Mirage JS único é sua capacidade de recriar cenários dinâmicos. Outros servidores de API simulados, como JSON Server e MSW , são bastante estáticos por natureza.

O Mirage JS funciona interceptando uma solicitação de rede feita pelo seu aplicativo JavaScript. Ele permite que você simule a resposta, o que permite desenvolver e testar seu aplicativo como se estivesse fazendo interface com um servidor ativo.

Outros recursos notáveis ​​do Mirage JS incluem:

  • Rotas para lidar com solicitações HTTP
  • Banco de dados e modelo para armazenamento de dados e tratamento de relacionamentos
  • Fábricas e instalações para serializar dados
  • Serializadores para formatar respostas HTTP

Exemplo Mirage JS

Para mostrar como funciona a simulação de API com Mirage JS, criaremos um aplicativo de notas usando Criar aplicativo React , que nos permite inicializar nosso projeto sem nos preocupar com as complexidades de configurar um aplicativo React manualmente.

Abra um terminal e execute o comando abaixo para criar um novo aplicativo React:

 notas npx create-react-app

Depois que o comando é executado com sucesso, ele inicializa um aplicativo React chamado notas . Navegue até o diretório raiz executando o comando abaixo:

 notas do cd

Assim que estiver no diretório raiz, execute o seguinte:

 npm start

Este comando inicia o servidor de desenvolvimento de nosso aplicativo React.

Configuração do Mirage JS

Antes de começarmos a simular as APIs necessárias para o aplicativo, execute o comando abaixo para adicionar Mirage JS ao projeto:

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

Depois de instalar a biblioteca Mirage JS com sucesso, navegue até o diretório src e crie um arquivo chamado server.js :

 cd src
touch server.js

Abra o arquivo server.js em um editor de sua escolha e cole o código abaixo:

 import {createServer} de'miragejs';
função de exportação makeServer () { let server=createServer (); servidor de retorno;
}

A função createServer é responsável por criar uma nova instância de servidor simulada. Vá para o arquivo index.js no diretório raiz e refatore-o para se parecer com o código abaixo:

 import React from'react';
importar ReactDOM de'react-dom';
import'./index.css';
importar App de'./components/App';
import {makeServer} de'./server'; if (process.env.NODE_ENV==='desenvolvimento') { makeServer ({ambiente:'desenvolvimento'});
}
ReactDOM.render (   , document.getElementById ('root')
);

No arquivo index.js refatorado, importamos a função makeServer que foi criada no arquivo server.js e a executamos: makeServer ({environment:'development'}) Observe que um argumento {environment:'development'} foi passado para a função makeServer ; isso nos permite executar sementes no ambiente de desenvolvimento, que veremos mais tarde.

Dados persistentes e propagação

Queremos que nosso aplicativo armazene dados como um servidor real e também carregue alguns dados existentes (sementes). Usaremos uma camada de dados Mirage JS chamada Model para criar uma coleção de notas para nosso aplicativo em seu banco de dados “in-memory”.

Abra o arquivo server.js e substitua o código existente pelo código abaixo:

 import {createServer, Model} de'miragejs';
função de exportação makeServer ({environment='test'}={}) { let server=createServer ({ ambiente, modelos: { notas: modelo, }, sementes (servidor) { server.create ('note', { título:'Nulla sit amet', corpo: -Praesent congue erat em massa. Pellentesque habitant morbi tristique senectus et netus et maleuada fames ac turpis egestas. Pellentesque commodo eros a enim. Nunc interdum lacus sit amet orci.', }); server.create ('note', { título:'Curabitur suscipit suscipit', corpo: 'Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Em enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Praesent nec nisl a purus blandit viverra.', }); server.create ('note', { título:'Donec id justo', corpo: 'Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Curabitur suscipit suscipit tellus. Praesent ac sem eget est egestas volutpat. Pellentesque posuere.', }); } servidor de retorno;
}

A opção ambiente na função createServer nos permite escolher entre desenvolvimento e teste . Se o ambiente estiver definido como development , o Mirage JS carregará as sementes e registrará todas as suas respostas no console. Definimos o ambiente para testar por padrão a partir do parâmetro padrão makeServer , {environment='test'}={} , para executar uma nova instância do servidor sem o sementes toda vez que precisamos fazer um teste. Também definimos uma coleção chamada notas na propriedade models da função createServer .

Como mencionado anteriormente, as sementes nos permitem criar dados iniciais. A função server.create nos permite criar novos registros de notas no modelo de notas que definimos. Os IDs são atribuídos automaticamente às sementes criadas.

Criação de rotas

Agora que configuramos com sucesso um servidor Mirage JS com um banco de dados e sementes iniciais, a próxima etapa é criar rotas. Nosso aplicativo de notas precisará das seguintes rotas:

  • OBTER /api/notes para buscar todos os registros de notas
  • OBTER /api/notes/: id para buscar um único registro de nota
  • POSTAR /api/notes para criar um novo registro de nota
  • PATCH /api/notes/: id para atualizar um registro de nota existente
  • DELETE /api/notes/: id para remover um registro de nota existente

Abra o arquivo server.js e substitua o código existente pelo seguinte:

 import {createServer, Model} de'miragejs';
função de exportação makeServer ({environment='test'}={}) { let server=createServer ({ ambiente, modelos: { notas: modelo, }, sementes (servidor) { server.create ('note', { título:'Nulla sit amet', corpo: -Praesent congue erat em Nhonhô. Pellentesque habitant morbi tristique senectus et netus et maleuada fames ac turpis egestas. Pellentesque commodo eros a enim. Nunc interdum lacus sit amet orci.', }); server.create ('note', { título:'Curabitur suscipit suscipit', corpo: 'Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Em enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Praesent nec nisl a purus blandit viverra.', }); server.create ('note', { título:'Donec id justo', corpo: 'Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Curabitur suscipit suscipit tellus. Praesent ac sem eget est egestas volutpat. Pellentesque posuere.', }); }, rotas () { this.namespace='api/notas'; this.get ('/', (esquema, solicitação)=> { return schema.notes.all (); }); this.get ('/: id', (esquema, solicitação)=> { let id=request.params.id; return schema.notes.find (id); }); this.post ('/', (esquema, solicitação)=> { deixe attrs=JSON.parse (request.requestBody); return schema.notes.create (attrs); }); this.patch ('/: id', (esquema, solicitação)=> { deixe newAttrs=JSON.parse (request.requestBody); let id=request.params.id; deixe observar=schema.notes.find (id); return note.update (newAttrs); }); this.delete ('/: id', (esquema, solicitação)=> { let id=request.params.id; return schema.notes.find (id).destroy (); }); }, }); servidor de retorno;
}

O gancho routes é onde as rotas para nosso aplicativo serão definidas. this.namespace='api/notes' nos permite definir o namespace da API para que não tenhamos que repetir em todas as rotas de nosso aplicativo, por exemplo, /api/notes/: id . this.get , this.post , this.patch e this.delete nos permitem simular os vários solicitações de rede. O argumento schema é usado para acessar dados do modelo notas que criamos anteriormente, enquanto o argumento request é usado para obter dados de nosso aplicativo.

Configuração do front-end

Neste ponto, terminamos a simulação de um servidor e criamos APIs simuladas. A próxima etapa é construir um front-end para acessar as APIs fictícias que criamos.

Abra um terminal e navegue até o diretório raiz. Cole o código abaixo para instalar as bibliotecas que usaremos para mostrar ícones e exibir mensagens de notificação em nosso aplicativo React:

 npm install react-icons react-toastify

Crie uma pasta chamada componentes no diretório src . Esta pasta hospedará os componentes que usaremos em nosso aplicativo.

Abra o arquivo index.css e cole o código abaixo:

 *,
*::antes,
*::depois de {
margem: 0;
preenchimento: 0;
dimensionamento da caixa: caixa de borda;
}
html {
tamanho da fonte: 62,5%;
comportamento de rolagem: suave;
}
corpo {
font-family:-apple-system, BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen', 'Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',
sem serifa;
cor de fundo: # 202124;
tamanho da fonte: 1.6rem;
cor: # e8eaed;
}
.container {
preenchimento: 2rem;
largura máxima: 100rem;
margem: 0 automático;
}
.header {
display: flex;
direção flexível: linha;
justify-content: espaço entre;
alinhar-itens: centro;
preenchimento: 2rem 0;
}
.btn {
cor de fundo: # 41331c;
preenchimento: 1rem 2rem;
cor: # e8eaed;
tamanho da fonte: 1.6rem;
borda: 1px sólido # 41331c;
raio da borda: 8px;
cursor: ponteiro;
peso da fonte: 700;
display: flex;
justificar o conteúdo: centro;
alinhar-itens: centro;
transição: todos os 0,5s;
}
.btn: hover,
.toolbox__btn: hover {
cor de fundo: # b38b4d;
}
.btn__icon {
margem esquerda: 5px;
}
.notes-container {
display: flex;
direção flexível: linha;
alinhar-itens: flex-start;
flex-wrap: wrap;
}
.notes-item {
margem: 1rem;
preenchimento: 1,5 rem;
borda: 1px sólido # 5f6368;
raio da borda: 8px;
cor: # e8eaed;
largura: 100%;
altura mínima: 6 rem;
cursor: ponteiro;
}
.notes-item h2 {
margem inferior: 1rem;
}
.notes-item p {
altura da linha: 2,5 rem;
tamanho da fonte: 1.4rem;
}
.Caixa de ferramentas {
display: flex;
direção flexível: linha;
justify-content: espaço entre;
alinhar-itens: centro;
preenchimento: 5px 0;
margem superior: 1rem;
}
.toolbox__btn {
preenchimento: 5px;
raio da borda: 50%;
cor de fundo: transparente;
fronteira: 0;
cursor: ponteiro;
}
.showModal {
display: bloco;
}
.hideModal {
Mostrar nenhum;
}
.modal {
posição: fixa;
índice z: 1;
esquerda: 0;
topo: 0;
largura: 100%;
altura: 100%;
estouro: automático;
cor de fundo: # 202124;
preenchimento: 4rem;
}
.go-back-container {
largura: 50%;
}
.volte {
cor de fundo: transparente;
tamanho da fonte: 1.6rem;
display: flex;
justificar o conteúdo: centro;
alinhar-itens: centro;
transição: todos os 0,5s;
cor: # e8eaed;
fronteira: 0;
cursor: ponteiro;
peso da fonte: 700;
preenchimento: 1rem 0;
}
.go-back span {
margem esquerda: 1rem;
}
.modal-form {
cor de fundo: transparente;
largura: 100%;
margem: 2rem automático;
}
.modal-form-input {
display: bloco;
margem: 2rem 0;
preenchimento: 1rem;
tamanho da fonte: 1.8rem;
borda: 2px sólido # 5f6368;
cor: # e8eaed;
cor de fundo: # 202124;
largura: 100%;
raio da borda: 8px;
}
@media (largura mínima: 768px) {
.modal-form {
largura: 50%;
}
.notes-item {
largura máxima: 30rem;
}
} 

Este arquivo contém os estilos que usaremos para o aplicativo.

Navegue até o diretório components que criamos e crie um arquivo chamado NoteItem.js . Abra o arquivo e cole o código abaixo:

 import React from'react';
importar {FaRegEdit, FaRegTrashAlt} de'react-icons/fa';
const NotesItem=({note, getNote, deleteNote})=> { Retorna ( 
getNote (note.id)}>

{note.title}

{note.body}

); }; exportar NotesItem padrão;

Este arquivo é um componente de reação para um único item de nota que usaremos em nossa Lista de notas. Navegue de volta para o diretório componentes e crie outro arquivo chamado NotesList.js , este arquivo conterá uma lista dos componentes NoteItems.js . Abra o arquivo e cole o código abaixo

 import React from'react';
importar NotesItem de'./NotesItem';
const NotesList=({notes, getNote, setToggle, deleteNote})=> { Retorna ( 
{notas && notes.map ((note)=> ( ))}
); }; exportar NotesList padrão;

Agora temos um componente para itens de notas e outro componente para as listas de itens de notas, agora crie um arquivo Form.js no diretório components para adicionar e atualizar notas. Depois de criar o arquivo, cole o código abaixo no arquivo criado

 import React, {useEffect} de'react';
importar {FaArrowCircleLeft} de'react-icons/fa';
Const Form=({ showModal, toggleModal, Nota, adicionar nota, updateNote, entradas, setInputs,
})=> { useEffect (()=> { if (note) { setInputs ({title: note.title, body: note.body}); } }, [note, setInputs]); const handleSubmit=(evento)=> { event.preventDefault (); const {título, corpo}=entradas; if (! note.id) { addNote (título, corpo); Retorna; } updateNote (note.id, título, corpo); }; const handleChange=(evento)=> { event.persist (); setInputs ((entradas)=> ({ ... entradas, [event.target.name]: event.target.value, })); }; Retorna (