Mockando APIs REST com json-server

Mockando APIs REST com json-server
Vinicios Neves
Vinicios Neves

Compartilhe

No dia a dia das empresas, é comum consumirmos APIs REST em nossos frontends. Eventualmente pode ser necessário desenvolvermos o frontend primeiro ou em paralelo, ao backend.

Quando isso acontece, temos de simular de alguma forma os dados enviados pelo backend, ou seja, dizemos que estamos trabalhando com mocks ou “mockando” o backend. Mock nada mais é que o nome dado para um conteúdo inventado e utilizado apenas como um marcador de posição.

Existem várias formas de se fazer isso. Uma delas, é pelo json-server. Resumidamente, o json-server vai simular uma API REST, com todos os endpoints de um recurso: GET, POST, PUT e DELETE. Assim, o nosso frontend consome essa API simulada, possibilitando a criação de toda a camada HTTP da aplicação.

Banner promocional da Alura, com um design futurista em tons de azul, apresentando o texto

O json-server é um pacote NPM que pode ser instalado globalmente em ambientes que possuam o Node.JS instalado. Então, nosso primeiro passo é executar a instalação:

npm install -g json-server

Feito isso, já podemos executar o comando json-server no terminal, a partir de qualquer diretório:

Terminal exibindo a saída do comando executado.

Temos várias opções disponíveis para uso, mas vamos começar criando um arquivo JSON que representará o nosso backend. Vamos criar dois recursos:

  • projetos;
  • tarefas.

O projeto é uma entidade simples, que possui um nome e um ID numérico e incremental. A tarefa possui uma descrição, um ID numérico e um projeto. Assim, podemos representá-los:

{
  "projetos": [
    {
      "id": 1,
      "nome": "Alura Tracker 3.0"
    },
    {
      "id": 2,
      "nome": "ByteBank 2.0"
    }
  ],
  "tarefas": [
    {
      "id": 1,
      "descricao": "Configuração do ambiente",
      "projeto": {
        "id": 1,
        "nome": "Alura Tracker 3.0"
      }
    },
    {
      "descricao": "Refatoração do vuex 4",
      "projeto": {
        "id": 1,
        "nome": "Alura Tracker 3.0"
      },
      "id": 2
    }
  ]
}

Repare que se trata de uma estrutura JSON simples. Vamos salvar esse arquivo como db.json. Temos um array com os projetos e outros com as tarefas, seguindo a estrutura definida anteriormente.

Agora, podemos executar o comando base:

json-server db.json
Terminal exibindo a saída do comando executado.

Acessando a rota de projetos:

Imagem exibindo o retorno da lista de projetos.

Assim, o db.json faz a coisa acontecer. Essas rotas são criadas a partir da estrutura do arquivo JSON. Logo, o que ocorre quando temos um array de tarefas e um de projetos? As duas rotas são criadas.

Inclusive, podemos ir além e criar um endpoint singular que vai retornar, por exemplo, os dados do usuário logado:

{
  "projetos": [
    {
      "id": 1,
      "nome": "Alura Tracker 3.0"
    },
    {
      "id": 2,
      "nome": "ByteBank 2.0"
    }
  ],
  "tarefas": [
    {
      "id": 1,
      "descricao": "Configuração do ambiente",
      "projeto": {
        "id": 1,
        "nome": "Alura Tracker 3.0"
      }
    },
    {
      "descricao": "Refatoração do vuex 4",
      "projeto": {
        "id": 1,
        "nome": "Alura Tracker 3.0"
      },
      "id": 2
    }
  ],
  "usuario": {
    "id": 13,
    "nome": "Nathália Neves",
    "perfil": "Administração"
  }
}

Como alteramos o db.json manualmente, temos que interromper o comando e iniciá-lo novamente para carregar as novas alterações. Sempre que o arquivo JSON for alterado, o ideal é que o json-server carregue automaticamente as novas informações. Então, vamos adicionar a opção --watch:

json-server db.json –watch
Terminal exibindo a saída do comando executado.

Repare que, de acordo com a estrutura do JSON, o json-server monta os endpoints da APIs. Agora, temos as três rotas disponíveis e ainda mantemos o json-server observando alterações no arquivo db.json.

Com o json-server rodando, podemos executar todas as operações em cada recurso. Usando o axios para fazer as requisições dos projetos, teríamos algo mais ou menos assim:

import axios from 'axios'

axios.get('http://localhost:3000/projetos')
    .then(resposta => console.log(resposta.data))

axios.get('http://localhost:3000/projetos/1')
    .then(resposta => console.log(resposta.data))

axios.post('http://localhost:3000/projetos', {
    nome: 'Novo projeto incrivel'
})
    .then(resposta => console.log(resposta.data))

axios.put('http://localhost:3000/projetos/1', {
    id: 1,
    nome: 'Novo projeto incrivel'
})
    .then(resposta => console.log(resposta.data))

axios.delete('http://localhost:3000/projetos/1')
    .then(resposta => console.log(resposta.data))

Temos várias outras funcionalidades, por exemplo, a de fazer uma busca utilizando uma propriedade específica:

import axios from 'axios'

axios.get('http://localhost:3000/projetos?nome=Alura Tracker 3.0')
    .then(resposta => console.log(resposta.data))

Ou uma busca mais genérica, utilizando todos as propriedades disponíveis:

import axios from 'axios'

axios.get('http://localhost:3000/projetos?q=alura')
    .then(resposta => console.log(resposta.data))

Tem muitas funcionalidades já prontas para uso, por exemplo, paginação:

import axios from 'axios'

axios.get('http://localhost:3000/projetos?_page=1&_limit=20)
    .then(resposta => console.log(resposta.data))

Agora, com um ótimo backend emulado, estamos prontos para seguir com o desenvolvimento do frontend até que a verdadeira API esteja disponível!

O json-server é uma ótima ferramenta para estar no cinto de utilidades de todas as pessoas desenvolvedoras. Se você quiser desvendar todo o potencial desse pacote, pode conferir a documentação completa aqui.

Vale ressaltar que, por baixo dos panos, o json-server usa o lowdb para escrever as alterações direto no arquivo JSON.

Nos objetos dentro do arquivo JSON que representa os nossos recursos, a propriedade id é imutável. Nós não conseguimos mudá-la fazendo PUT ou PATCH. Via de regra, não adianta passar a id no corpo da requisição, pois ela será ignorada.

Embora o axios faça isso por padrão, é mandatório o envio do header Content-Type: application/json para que as requisições sejam processadas corretamente caso as requisições HTTP sejam realizadas de outra forma.

Se você quer mergulhar ainda mais profundo do lado do backend, você pode aprender como construir APIs REST utilizando NodeJS, por exemplo. Agora, se o frontend é mais a sua praia, aqui você vai conhecer uma alternativa ao axios para fazer requisições web.

Vinicios Neves
Vinicios Neves

Vinicios Neves, Tech Lead e Educador, mistura código e didática há mais de uma década. Especialista em TypeScript, lidera equipes full-stack em Lisboa e inspira futuros desenvolvedores na FIAP e Alura. Com um pé no código e outro no ensino, ele prova que a verdadeira engenharia de software vai além das linhas de código. Além de, claro, ser senior em falar que depende.

Veja outros artigos sobre Front-end