Guia Completo sobre o Middleware express.json do Express.js

O que é express.json()?

O express.json() é uma função de middleware integrada do Express.js (disponível a partir da versão 4.16.0), cuja função principal é analisar os dados no corpo de requisições HTTP no formato JSON, convertendo-os em objetos JavaScript e anexando-os à propriedade req.body para uso posterior por rotas e outros middlewares.

Em termos simples: quando um cliente envia dados no formato JSON para o servidor (por exemplo, em requisições POST/PUT), sem o uso do express.json(), o req.body do seria undefined. Com ele, você pode acessar diretamente os dados JSON analizados através de req.body.

Informação adicional: Antes do Express 4.16.0, a análise de corpos de requisição JSON dependia de middlewares de terceiros (como body-parser). Posteriormente, o Express incorporou as funcionalidades principais do body-parser, e o express.json() essencialmente é uma versão embutida do body-parser.json().

Por que precisamos do express.json()?

O corpo de uma requisição HTTP é, em sua essência, um "fluxo de dados binários". Mesmo quando o cliente envia uma string JSON (como {"username":"joao","idade":30}), os dados brutos recebidos pelo servidor são uma sequência de caracteres não estruturados, não um objeto JavaScript diretamente utilizável.

Sem o express.json() para fazer a análise:

  • Você precisaria monitorar manualmente os eventos data e end do objeto req para concatenar o fluxo de dados brutos;
  • Manualmente converter a string concatenada em um objeto JS (JSON.parse());
  • Lidar com codificação, exceções (como formato JSON inválido) e outros problemas, o que é extremamente trabalhoso.

O express.json() encapsula essa série de operações, permitindo que acessemos dados estruturados diretamente através de req.body, aumentando a eficiência do desenvolvimento.

Uso Básico: Como utilizar o express.json()?

1. Uso Global (Recomendado - analisa todas as requisições qualificadas)

Registre-o na instância Express usando app.use(), afetando todas as rotas subsqeuentes:

// 1. Importar Express
const servidorExpress = require('express');
// 2. Criar instância Express
const app = servidorExpress();
// 3. Registrar middleware express.json() (efeito global)
app.use(express.json());

// 4. Definir rota, usando req.body para obter dados JSON analisados
app.post('/api/usuario', (req, res) => {
  // Agora req.body foi analisado em um objeto JS
  console.log('Dados JSON analisados:', req.body);
  console.log('Nome de usuário:', req.body.nome);
  console.log('Idade:', req.body.idade);

  res.status(200).json({
    codigo: 200,
    mensagem: 'Requisição bem-sucedida',
    dados: req.body
  });
});

// 5. Iniciar servidor
const porta = 3000;
app.listen(porta, () => {
  console.log(`Servidor rodando em http://localhost:${porta}`);
});

2. Uso Local (apenas para rotas específicas)

Se você precisar analisar apenas algumas rotas de corpos de requisição JSON, pode registrar separadamente na definição da rota:

const servidorExpress = require('express');
const app = servidorExpress();

// Apenas para a rota POST /api/pedido
app.post('/api/pedido', express.json(), (req, res) => {
  console.log('Dados do pedido:', req.body);
  res.json({ codigo: 200, dados: req.body });
});

// Outras rotas não analisam corpo JSON (req.body será undefined)
app.post('/api/teste', (req, res) => {
  console.log('req.body não analisado:', req.body); // undefined
  res.send('Rota de teste');
});

app.listen(3000, () => console.log('Servidor iniciado'));

3. Teste e Validação

Você pode usar Postman, curl ou Axios para enviar requisições JSON de teste:

(1) Teste com comando curl

curl -X POST \
  http://localhost:3000/api/usuario \
  -H 'Content-Type: application/json' \
  -d '{
    "nome": "joao",
    "idade": 30,
    "genero": "masculino"
  }'

(2) Teste com frontend Axios

axios.post('http://localhost:3000/api/usuario', {
  nome: 'joao',
  idade: 30,
  genero: 'masculino'
}, {
  headers: {
    'Content-Type': 'application/json' // O frontend precisa especificar este cabeçalho (já incluído por padrão)
  }
}).then(res => console.log(res.data));

(3) Resultado da Resposta

O console do servidor exibirá:

Dados JSON analisados: { nome: 'joao', idade: 30, genero: 'masculino' }
Nome de usuário: joao
Idade: 30

O cliente receberá a resposta:

{
  "codigo": 200,
  "mensagem": "Requisição bem-sucedida",
  "dados": {
    "nome": "joao",
    "idade": 30,
    "genero": "masculino"
  }
}

Configuração Avançada: Parâmetros Opcionais do express.json()

O express.json() aceita um objeto de configuração para personalizar o comportamento de análise, com os seguintes parâmetros comuns:

Parâmetro Tipo Valor Padrão Descrição
inflar Booleano true Se deve analisar corpos de requisição em formato "comprimido" (como dados JSON compactados com gzip/deflate); definido como false rejeita corpos de requisição compactados
limite Texto/Número '100kb' Limita o tamanho do corpo da requisição; pode ser número (unidade: bytes) ou string (como '1mb', '2kb'); exceder esse tamanho gera erro 413 (Payload Too Large)
reviver Função null Segundo parâmetro passado para JSON.parse(), usado para personalizar o processo de análise (como converter strings de data em objetos Date)
estrito Booleano true Se deve ativar o "modo estrito"; quando true, analisa apenas formatos JSON de "objeto/matriz" (rejeitando strings/números/booleanos individuais); quando false permite analisar valores individuais
tipo Texto/Array/Função 'application/json' Especifica o cabeçalho Content-Type da requisição a ser analisado; pode ser string, array ou função de verificação personalizada
verificar Função undefined Função de verificação para validar o corpo da requisição; recebe (req, res, buf, encoding) como parâmetros, lançando erro para rejeitar a requisição

Exemplos de Configuração

(1) Limitar tamanho do corpo da requisição

// Limita corpo da requisição a 2MB
app.use(express.json({ limite: '2mb' }));

(2) Desativar modo estrito, permitindo analisar valores JSON individuais

app.use(express.json({ estrito: false }));

// Agora pode analisar {"nome":"joao"} (objeto) e também "hello" (string)/123 (número)
app.post('/api/teste', (req, res) => {
  console.log(req.body); // Se corpo for "hello", req.body será "hello"
  res.send(req.body);
});

(3) Usar reviver para converter strings de data em objetos Date

app.use(express.json({
  reviver: (chave, valor) => {
    // Corresponde a strings de data no formato ISO (como "2025-12-19T08:00:00.000Z")
    if (typeof valor === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(valor)) {
      return new Date(valor);
    }
    return valor;
  }
}));

app.post('/api/data', (req, res) => {
  console.log('Valor original:', req.body.aniversario); // Originalmente string, agora objeto Date
  console.log('Data formatada:', req.body.aniversario.toLocaleDateString());
  res.json({ aniversario: req.body.aniversario });
});

(4) Personalizar Content-Type analisado

Padrão analisa apenas Content-Type: application/json. Para analisar tipos personalizados (como application/vnd.meuapp+json):

// Método 1: string
app.use(express.json({ tipo: 'application/vnd.meuapp+json' }));

// Método 2: array (suporta múltiplos tipos)
app.use(express.json({ tipo: ['application/json', 'application/vnd.meuapp+json'] }));

// Método 3: função de verificação personalizada (retorna true para analisar)
app.use(express.json({
  tipo: (req) => {
    // Corresponde a todos os Content-Type terminados em "json"
    return req.headers['content-type']?.endsWith('json');
  }
}));

(5) Usar verificar para validar corpo da requisição

app.use(express.json({
  verificar: (req, res, buf, encoding) => {
    // buf é o Buffer de dados brutos do corpo, encoding é o formato de codificação
    const corpoStr = buf.toString(encoding);
    // Validação: nome de usuário deve ter pelo menos 3 caracteres
    const dados = JSON.parse(corpoStr);
    if (!dados.nome || dados.nome.length < 3) {
      throw new Error('Nome de usuário deve ter pelo menos 3 caracteres'); // Lança erro, requisição será rejeitada
    }
  }
}));

// Middleware de tratamento de erro (captura erros lançados por verificar)
app.use((err, req, res, proximo) => {
  res.status(400).json({ codigo: 400, mensagem: err.message });
});

Princípios Internos: Como o express.json() funciona?

O express.json() essencialmente é uma encapsulação do módulo body-parser, cujo fluxo de trabalho pode ser resumido em 5 passos:

  1. Verificar se precisa analisar
    Primeiro, verifica se o Content-Type da requisição corresponde ao parâmetro tipo configurado (padrão application/json). Se não corresponder, pula diretamente sem analisar.
  2. Processar corpo de requisição comprimido
    Se o corpo da requisição estiver em formato comprimido (gzip/deflate) e inflar: true, primeiro descompacta automaticamente para a string original.
  3. Concatenar fluxo de dados do corpo
    O corpo de requisição HTTP pode ser transmitido em blocos (problemas de TCP "colado/dividido"), o express.json() monitora o evento data do objeto req, concatenando gradualmente todos os blocos de dados até o evento end ser disparado (indicando conclusão da transmisão de dados).
  4. Validação e Análise
    • Valida se o tamanho do corpo excede o limite limite, excedendo lança erro 413;
    • Se estrito: true, valida se o formato JSON é objeto/matriz, caso contrário lança erro 400;
    • Chama JSON.parse() (passando parâmetro reviver) para converter string JSON em objeto JS.
  5. Anexar a req.body
    Anexa o objeto JS enalisado à propriedade req.body, então chama o método next(), passando a requisição para a próxima rota/middleware.

Pseudocódigo simplificado da implementação:

function expressJson(opcoes = {}) {
  // Configuração padrão
  const opcoesPadrao = {
    inflar: true,
    limite: '100kb',
    estrito: true,
    tipo: 'application/json',
    reviver: null
  };
  const opts = { ...opcoesPadrao, ...opcoes };

  return (req, res, proximo) => {
    // 1. Verificar se precisa analisar
    const contentType = req.headers['content-type'];
    if (!isMatchContentType(contentType, opts.tipo)) {
      return proximo();
    }

    let corpoBruto = Buffer.alloc(0);
    // 2. Concatenar fluxo de dados
    req.on('data', (pedaco) => {
      corpoBruto = Buffer.concat([corpoBruto, pedaco]);
      // 3. Validar tamanho
      if (corpoBruto.length > getLimitBytes(opts.limite)) {
        return proximo(new Error('Payload Too Large'));
      }
    });

    // 4. Após conclusão da transmissão de dados, analisar
    req.on('end', () => {
      try {
        const corpoStr = corpoBruto.toString('utf8');
        // Validação modo estrito
        if (opts.estrito && !/^\{|\[/.test(corpoStr.trim())) {
          throw new Error('Invalid JSON (modo estrito)');
        }
        // Análise JSON
        const dadosAnalisados = JSON.parse(corpoStr, opts.reviver);
        // Anexar a req.body
        req.body = dadosAnalisados;
        proximo();
      } catch (err) {
        proximo(new Error(`Invalid JSON: ${err.message}`));
      }
    });
  };
}

Problemas Comuns e Soluções

1. Problema: req.body é undefined

Análise de Causas:

  • Middleware express.json() não registrado;
  • Ordem de registro incorreta do middleware (registrado após as rotas, fazendo com que as rotas executem antes da análise);
  • Cabeçalho Content-Type da requisição do cliente não é application/json (ou não corresponde ao tipo personalizado);
  • Corpo da requisição não é JSON válido (análise falha, mas req.body pode ser {} ou lançar erro).

Soluções:

  • Certifique-se de registrar express.json() antes das rotas (app.use(express.json()) antes de app.post()/app.get());
  • Quando enviar requisição, defina explicitamente Content-Type: application/json;
  • Verifique se o corpo da requisição é JSON válido (evitar erros de sintaxe: vírgulas extras, nomes de chaves sem aspas duplas, etc.).

2. Problema: Erro 'Payload Too Large'

Análise de Causas:

O tamanho do corpo da requisição excede o limite configurado no express.json() (padrão 100kb).

Solução:

Aumente o valor do parâmetro limite:

// Aumentar para 2MB
app.use(express.json({ limite: '2mb' }));
// Ou aumentar para 10MB
app.use(express.json({ limite: '10mb' }));

3. Problema: Erro 'Invalid JSON'

Análise de Causas:

  • Corpo da requisição não é JSON válido (como aspas simples em chaves, erros de sintaxe, vírgulas extras, etc.); li>Modo estrito (estrito: true) ativado, mas corpo da requisição é string/número/booleano individual (como "hello", 123).

Soluções:

  • Corrija o formato JSON do corpo (use aspas duplas para chaves e strings, evite erros de sintaxe);
  • Se precisar suportar valores JSON individuais, desative o modo estrito: express.json({ estrito: false }).

4. Problema: Tipo de dados analisado não corresponde ao esperado

Análise de Causas:

Formato JSON não possui "tipo de data", datas são serializadas como strings, e por padrão, após análise, ainda permanecem strings, não objetos Date.

Solução:

Use o parâmetro reviver para personalizar a análise, convertendo strings de data em objetos Date (consulte o exemplo anterior em "Configuração Avançada").

5. Problema: Content-Type personalizado não é analisado

Análise de Causas:

express.json() analisa apenas application/json por padrão, e o Content-Type personalizado não foi configurado no parâmetro tipo.

Solução:

Especifique o Content-Type personalizado através do parâmetro tipo (consulte o exemplo anterior em "Configuração Avançada").

Diferenças entre outros middlewares de análise de corpo de requisição

O Express possui outros middlewares de análise de corpo de requisição integrados, sendo importante distinguir-los do express.json():

Middleware Função Content-Type analisado Cenário de uso
express.json() Analisar corpo de requisição em formato JSON application/json Projetos com separação frontend/backend (requisições AJAX/axios)
express.urlencoded() Analisar corpo de requisição em formato de codificação URL application/x-www-form-urlencoded Envio de formulário tradicional (formato padrão de tags form)
express.raw() Analisar corpo de requisição binário bruto Tipos personalizados (como application/octet-stream) Recebimento de fluxos de arquivos, dados binários
express.text() Analisar corpo de requisição em texto puro Tipos personalizados (como text/plain) Recebimento de strings de texto puro

Exemplo: Registrar múltiplos middlewares de análise

// Analisar formato JSON
app.use(express.json());
// Analisar formato de codificação URL (extended: true suporta objetos aninhados)
app.use(express.urlencoded({ extended: true }));
// Analisar formato texto puro
app.use(express.text({ tipo: 'text/plain' }));
// Analisar formato binário bruto
app.use(express.raw({ tipo: 'application/octet-stream', limite: '10mb' }));

Tags: express.js middleware Node.js JSON req.body

Publicado em 6-4 05:31 por Thomas