Skip to main content

Como criar um servidor de API simulado em JavaScript

Escrito por

David Ekete

feature mock api js

20 de outubro de 2022

0 minutos de leitura

Desenvolver e testar um recurso de frontend pode ser difícil, especialmente quando o backend do qual ele depende ainda não está pronto. Essa dependência de uma API de backend costuma atrasar o processo de desenvolvimento.

Em situações como essa, criar uma API simulada pode economizar bastante tempo: você desenvolve o recurso sem depender do backend e facilita os testes e a identificação de situações em que a API pode falhar antes de ficar pronta.

Neste artigo, você vai aprender mais sobre servidores de API simulados, as ferramentas que pode usar para criá-los, como eles podem acelerar o desenvolvimento e os testes e como configurar um servidor simulado simples.

O que é um servidor de API simulado?

Um servidor de API simulado é uma simulação de servidor de API que fornece respostas realistas às solicitações recebidas de um cliente. Normalmente, ele substitui um servidor de backend que ainda está em desenvolvimento.

Um servidor de API simulado imita uma API real usando dados provisórios com valores de resposta realistas, mas sem muitas das características funcionais e não funcionais do componente original, como a persistência de dados.

Servidores de API simulados podem ser usados em várias situações, incluindo:

  • Desenvolvimento: servidores de API simulados eliminam temporariamente a dependência entre as equipes de frontend e backend, permitindo que trabalhem, desenvolvam e testem seus componentes de forma independente.

  • Testes: servidores de API simulados facilitam os testes, uma etapa essencial do desenvolvimento de software, permitindo que a equipe de frontend teste seus recursos sem esperar que a equipe de backend desenvolva uma API totalmente funcional. Eles também evitam que a API real seja contaminada por dados de teste, pois todas as chamadas de teste são feitas ao servidor simulado, e não ao real.

  • Componentes externos: servidores de API simulados também ajudam a simular dependências externas ao usar ferramentas como Storybook para demonstrar recursos de frontend.

Boas práticas para APIs simuladas

Ao criar um servidor de API simulado, leve em conta estas boas práticas:

  • Uma API simulada deve oferecer suporte ao mesmo esquema e às mesmas interfaces da API real. Assim, as respostas serão mais realistas.

  • Se seu aplicativo depende de serviços externos, sua API simulada também deve simulá-los.

  • Uma API simulada deve oferecer suporte ao encaminhamento de solicitações. Isso permite fazer a transição gradual de respostas simuladas para respostas reais quando a API estiver pronta.

  • Uma API simulada deve conseguir reproduzir erros inesperados, lentidão e entradas inválidas dos usuários. Assim, seus aplicativos poderão lidar corretamente com essas situações.

Ferramentas de simulação de APIs

Há muitas ferramentas que ajudam a criar servidores de API simulados. Algumas delas são:

  • Mock Service Worker (MSW): o Mock Service Worker é uma biblioteca de simulação de APIs que usa a Service Worker API. Essa API permite que o MSW intercepte solicitações reais e retorne respostas simuladas, atuando como um servidor proxy. As interceptações acontecem na camada de rede, garantindo que seu aplicativo não saiba que as respostas vêm de uma API simulada.

  • Postman: o Postman é uma plataforma para criar, usar, testar e documentar APIs. Ele também permite criar servidores de API simulados que retornam dados simulados salvos. O Postman compara a configuração da solicitação com os exemplos salvos e retorna os dados que mais correspondem a essa configuração. Sua interface gráfica interativa facilita bastante a configuração de um servidor simulado.

  • Mirage JS: o Mirage JS é uma biblioteca de simulação de APIs que permite criar e testar um aplicativo JavaScript sem depender de serviços de backend. Com ele, é fácil criar cenários dinâmicos e tornar sua API simulada mais realista. Graças à capacidade de criar cenários dinâmicos e ao banco de dados em memória, o Mirage JS oferece mais flexibilidade para criar servidores de API simulados.

Como criar um servidor de API simulado com Mirage JS

Nesta seção, você vai aprender a criar um servidor de API simulado simples com Mirage JS.

Pré-requisitos

Antes de começar, você precisa ter:

  • O Node.js v16 ou superior instalado no sistema.

  • O IDE de sua preferência.

  • Conhecimentos básicos de React.js.

Para acompanhar o tutorial no editor, comece clonando o repositório do tutorial no GitHub.

Configurando o servidor simulado

Execute os comandos a seguir no terminal para instalar as dependências necessárias e iniciar o servidor de desenvolvimento:

npm install
npm run start

Você verá um componente giratório, mas nenhum recurso do aplicativo estará funcionando. Isso acontece porque o aplicativo está tentando buscar dados de uma API que ainda não está pronta. Para acelerar o desenvolvimento, você vai criar um servidor simulado.

Tela de carregamento de um aplicativo React com um indicador circular azul sobre um fundo verde-azulado

No diretório src, crie um arquivo chamado mock.js e adicione o bloco de código abaixo:

//mock.js
import { createServer } from "miragejs";

const createMockServer = function () {
 let server = createServer();

 return server;
};

export default createMockServer;

No bloco de código acima, você importou createServer de miragejs. Essa função inicia um servidor Mirage com um objeto de configuração. Esse objeto pode conter informações como as várias rotas que o servidor vai atender, um banco de dados simulado em memória e um namespace.

A função createMockServer é responsável por criar e retornar a instância.

Criando um banco de dados simulado em memória

Em seguida, você vai criar um banco de dados simulado simples usando a camada de dados do Mirage para armazenar e retornar dados.

Atualize o arquivo mock.js para que corresponda ao bloco de código abaixo:

//mock.js
import { createServer, Model } from "miragejs";

const createMockServer = function () {
 let server = createServer({
   models: {
     todos: Model
   },
 });

 return server;
};

export default createMockServer;

No bloco de código atualizado, você também está importando Model, a definição base dos modelos do Mirage, de miragejs.

Em seguida, você passou um objeto de configuração como argumento para createServer. Dentro do objeto de configuração, a propriedade models recebe um objeto; e, dentro desse objeto da propriedade models, todos recebe model. Isso instrui o Mirage a criar uma coleção todos vazia no banco de dados em memória.

Carregando dados no banco de dados em memória

Em seguida, você vai adicionar manualmente alguns dados ao banco de dados em memória usando o hook seeds. O hook seeds permite preencher o Mirage com dados iniciais para que sua API simulada tenha dados para exibir quando o aplicativo for iniciado pela primeira vez.

Para carregar dados iniciais no banco, adicione o bloco de código a seguir abaixo da propriedade models no objeto de configuração de createServer:

    //mock.js
   seeds(server) {
    server.create("todo", {
      id: 1,
      title: "Reach out to a friend",
      completed: true,
    });

    server.create("todo", {
      id: 2,
      title: "Make breakfast",
      completed: true,
    });

    server.create("todo", {
      id: 3,
      title: "Text John Doe",
      completed: false,
    });
  },

No bloco de código acima, você adicionou o hook seeds ao objeto de configuração. O hook seeds recebe uma instância do servidor como argumento.

Em seguida, você adicionou dados ao banco de dados em memória chamando o método create na instância do servidor. O método create recebe dois argumentos: o nome no singular (por exemplo, "todos" vira "todo") da coleção em que os dados serão salvos e os dados que você quer salvar.

Definindo os manipuladores de rotas simuladas

Em seguida, você precisa definir os manipuladores de rotas usando o hook routes. O hook routes permite especificar manipuladores de rotas para cada caminho disponível e solicitação HTTP.

Adicione o bloco de código a seguir diretamente abaixo do hook seeds no objeto de configuração de createServer para incluir os manipuladores de rotas das chamadas à API:

routes() {
    this.namespace = "api/todos";

    this.get("/", (schema, request) => {
      return schema.todos.all().models
    });
  },

No bloco de código acima, você usou o hook routes para definir um namespace global para todos os manipuladores de rotas (api/todos), evitando ter que repeti-lo em cada manipulador.

Em seguida, você definiu um manipulador de rota GET com o método get, que recebe um caminho e uma função de callback. Nela, o aplicativo tem acesso ao argumento schema, usado para acessar o banco de dados em memória, e ao argumento request, que permite acessar o corpo da solicitação.

Por fim, você retornou todos os todos do banco de dados em memória chamando o método all em schema.todos. Você pode acessar o modelo em memória encadeando seu nome ao argumento schema. O método all retorna um objeto Collection com duas propriedades: modelName e models.

A propriedade modelName é o nome do modelo, e a propriedade models é uma matriz que contém os dados carregados.

Defina o manipulador de rota POST adicionando o código a seguir ao hook routes:

  this.post("/new", (schema, request) => {
       let attrs = JSON.parse(request.requestBody);
       attrs.completed = false;

       return schema.todos.create(attrs);
   });

Na função de callback acima, você obtém e analisa o corpo da solicitação a partir do objeto request. Em seguida, define a propriedade completed como false, pois, por padrão, novas tarefas não devem estar concluídas. O Mirage atribui automaticamente um id exclusivo a cada novo todo, incrementando o id do último todo carregado inicialmente no banco de dados em memória. Por fim, você usou o método `create`` para adicionar o novo todo ao banco de dados.

Em seguida, defina o manipulador de rota PATCH adicionando o código a seguir ao hook routes:

   this.patch("/:id", (schema, request) => {
       let newAttrs = JSON.parse(request.requestBody);
       let { id } = request.params;
       let todo = schema.todos.find(id);
       return todo.update(newAttrs);
   });

Na função de callback acima, você recupera e analisa o corpo da solicitação a partir do objeto request. Em seguida, extrai a propriedade id do objeto params associado ao corpo da solicitação. Com o método find, você consulta o banco de dados em memória em busca de um todo com o id correspondente. Por fim, atualiza o todo usando o método update.

Defina o manipulador de rota DELETE adicionando o código a seguir ao hook routes:

  this.delete("/:id", (schema, request) => {
       let { id } = request.params;
       return schema.todos.find(id).destroy();
   });

Nessa função, você extraiu a propriedade id do objeto params associado ao corpo da solicitação. Em seguida, usando o método find, consultou o banco de dados em memória em busca de um todo com o id correspondente e chamou o método destroy para removê-lo do banco.

Seu servidor simulado completo deve ficar assim:

import { createServer, Model } from "miragejs";

const createMockServer = function () {
 let server = createServer({
   models: {
     todos: Model,
   },

   seeds(server) {
     server.create("todo", {
       id: 1,
       title: "Reach out to a friend",
       completed: true,
     });

     server.create("todo", {
       id: 2,
       title: "Make breakfast",
       completed: true,
     });

     server.create("todo", {
       id: 3,
       title: "Text John Doe",
       completed: false,
     });
   },

   routes() {
     this.namespace = "api/todos";

     this.get("/", (schema, request) => {
       return schema.todos.all().models;
     });

     this.post("/new", (schema, request) => {
       let attrs = JSON.parse(request.requestBody);
       attrs.completed = false;

       return schema.todos.create(attrs);
     });

     this.patch("/:id", (schema, request) => {
       let newAttrs = JSON.parse(request.requestBody);
       let id = request.params.id;
       let todo = schema.todos.find(id);
       return todo.update(newAttrs);
     });

     this.delete("/:id", (schema, request) => {
       let id = request.params.id;
       return schema.todos.find(id).destroy();
     });
   },
 });

 return server;
};

export default createMockServer;

Por fim, importe a função createMockServer no arquivo App.js e inicie o servidor simulado chamando a função createMockServer no arquivo App.js.

Por exemplo:

//app.js
import createMockServer from "./mock";

createMockServer();

Ao abrir seu aplicativo React, você deverá ver o app de tarefas exibindo os dados carregados da API simulada.

Aplicativo de lista de tarefas mostrando tarefas concluídas, uma tarefa “Enviar mensagem para John Doe” desmarcada e um campo para adicionar uma nova tarefa

Agora você pode testar seu app de tarefas como faria com uma API de backend real.

Conclusão sobre servidores de API simulados

Neste artigo, você aprendeu sobre servidores de API simulados, sua importância, as boas práticas para criá-los e as ferramentas que podem ajudar. Também aprendeu a criar um servidor de API simulado simples usando Mirage JS.

Incluir servidores de API simulados no processo de desenvolvimento vai acelerar o trabalho e permitir que você trabalhe de forma independente, melhorando o fluxo de trabalho.

Publicado em: