Como criar um endpoint REST customizado no WordPress (passo a passo)

Mais cedo ou mais tarde todo dev WordPress precisa expor um dado para fora do site: alimentar um app, um front headless em React, um painel interno ou uma integração com outro sistema. A boa notícia é que o WordPress já tem uma API REST embutida — e criar a sua rota é mais simples do que parece. Neste passo a passo você vai criar um endpoint do zero, com filtros, sanitização, controle de acesso e uma rota com parâmetro na URL. No fim, é só chamar /wp-json/meusite/v1/produtos e receber JSON.

O que você vai precisar

    • Um WordPress rodando (local ou em produção).
    • Acesso ao functions.php do tema ou a um plugin próprio.
    • Noções básicas de PHP. Nada além disso.

Passo 1 — Onde colocar o código

Você pode escrever no functions.php do tema, mas a melhor prática é criar um plugin pequeno — assim a sua API continua funcionando mesmo se você trocar de tema. Crie o arquivo wp-content/plugins/minha-api/minha-api.php com um cabeçalho de plugin e ative-o no painel:
				
					<?php
/*
 * Plugin Name: Minha API
 * Description: Endpoints REST customizados do site.
 * Version: 1.0.0
 */
if (!defined('ABSPATH')) exit;
				
			

Passo 2 — Registrar a rota

Toda rota é registrada no hook rest_api_init com a função register_rest_route(). Repare em duas coisas: o namespace versionado (meusite/v1) — versionar evita quebrar quem já consome a API — e o permission_callback, que é obrigatório.

				
					add_action('rest_api_init', function () {
    register_rest_route('meusite/v1', '/produtos', array(
        'methods'             =&gt; 'GET',
        'callback'            =&gt; 'meusite_listar_produtos',
        'permission_callback' =&gt; '__return_true', // pública por enquanto
    ));
});
				
			

Passo 3 — O callback que devolve os dados

O callback recebe a requisição e devolve um WP_REST_Response. Aqui usei dados fixos para o exemplo, mas é onde você faria sua consulta com WP_Query, $wpdb ou o que precisar.

				
					function meusite_listar_produtos($request) {
    $produtos = array(
        array('id' =&gt; 1, 'nome' =&gt; 'Camiseta', 'preco' =&gt; 79.9),
        array('id' =&gt; 2, 'nome' =&gt; 'Caneca',   'preco' =&gt; 39.9),
    );

    return new WP_REST_Response($produtos, 200);
}
				
			

Pronto: já dá para abrir /wp-json/meusite/v1/produtos no navegador e ver o JSON.

Passo 4 — Receber e sanitizar parâmetros

Filtros chegam pela query string (?q=...&per_page=...). Nunca confie no que vem do usuário: sanitize tudo e limite os valores. É a diferença entre uma API segura e um convite a problemas.

				
					function meusite_listar_produtos($request) {
    $busca = sanitize_text_field($request-&gt;get_param('q'));

    $por_pagina = (int) $request-&gt;get_param('per_page');
    if ($por_pagina &lt; 1)   $por_pagina = 10;
    if ($por_pagina &gt; 100) $por_pagina = 100;

    // ... use $busca e $por_pagina na sua consulta ...

    return new WP_REST_Response(array(
        'busca'      =&gt; $busca,
        'por_pagina' =&gt; $por_pagina,
        'itens'      =&gt; array(),
    ), 200);
}
				
			

Passo 5 — Controlar o acesso

Use '__return_true' só quando o dado for realmente público (um catálogo, por exemplo). Para qualquer coisa sensível, valide a permissão no permission_callback:

				
					'permission_callback' =&gt; function () {
    return current_user_can('edit_posts');
},
				
			

Passo 6 — Uma rota com parâmetro na URL

Para buscar um item específico (ex.: /produtos/1), declare o parâmetro com uma expressão regular no caminho:

				
					register_rest_route('meusite/v1', '/produtos/(?P&lt;id&gt;\d+)', array(
    'methods'             =&gt; 'GET',
    'callback'            =&gt; 'meusite_obter_produto',
    'permission_callback' =&gt; '__return_true',
));

function meusite_obter_produto($request) {
    $id = (int) $request['id'];

    if ($id !== 1) {
        return new WP_Error('nao_encontrado', 'Produto não encontrado.', array('status' =&gt; 404));
    }

    return new WP_REST_Response(array('id' =&gt; 1, 'nome' =&gt; 'Camiseta'), 200);
}
				
			

Passo 7 — Testar

No navegador, abra a URL. No terminal, use curl para ver também o status e os headers:

				
					curl "https://seusite.com.br/wp-json/meusite/v1/produtos?per_page=5"
curl "https://seusite.com.br/wp-json/meusite/v1/produtos/1"
				
			

Se o seu site não usa permalinks "bonitos", a forma alternativa é ?rest_route=/meusite/v1/produtos.

Boas práticas para levar para produção

  • Versione o namespace (v1, v2): você muda a API sem quebrar quem já consome.
  • Sanitize a entrada, controle a saída: nunca exponha campos sensíveis (e-mail, telefone, dados internos) sem necessidade.
  • Pagine listas grandes (page/per_page) e devolva o total nos headers.
  • Pense no consumidor: se um front em outro domínio vai chamar a API, configure o CORS.
  • Cacheie respostas pesadas para não sobrecarregar o banco a cada requisição.

Conclusão

Com register_rest_route(), um callback e um pouco de cuidado com segurança, o seu WordPress vira um back-end pronto para alimentar apps, fronts headless e integrações. É o mesmo padrão que usamos em projetos reais aqui na InfotechJS para servir catálogos e conectar sistemas.

Quer transformar o seu WordPress em um CMS headless ou integrá-lo a outro sistema? Fale com a gente.

💡 assuntos relacionados:

Widgets de blocos atômicos do Elementor V4

Novos widgets de blocos aômicos do elementor V4

🚀 NOVIDADE NO ELEMENTOR V4!

Os novos Widgets de Blocos Atômicos chegaram e
estão deixando os sites 3X MAIS RÁPIDOS! ⚡

✅ Código mais limpo
✅ Melhor performance
✅ Sites mais leves
✅ Google ama!

Já atualizou? Conta aqui nos comentários! 👇

#Elementor #WordPress #WebDesign #InfotechJS

Leia mais »

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *