A API REST do WordPress

  • Last modified: 5 de agosto de 2024
  • Reading time: 77 mins

Um dos meus objetivos, tanto aqui no blog quanto no canal do YouTube, é desmistificar assuntos do WordPress que, mesmo sendo simples, acabam sendo vendidos como extremamente complicados. Um deles é a API REST do WordPress.

O artigo é grande, mas quando terminar a leitura você vai entender tudo sobre a API REST do WP, então pega um lanche e lê (ou assiste) aí!

Antes de falar de nomes e conceitos, o melhor é ver logo o que é a API REST do WordPress. É algo simples e que já é nativo do WP desde a versão 4.7. Se você instalar o WP, sem plugin nenhum, e acessar http://localhost/?rest_route=/wp/v2/posts pelo seu navegador você vai ver um código JSON. Se você jogar essa massaroca de código em um site como o JSON Formatter ou olhar pela aba Network das ferramentas de desenvolvedor do seu navegador, o código vai ser parecido com isso aqui:

JSON
[
  {
    "id": 1,
    "date": "2019-07-05T09:23:31",
    "date_gmt": "2019-07-05T12:23:31",
    "guid": {
      "rendered": "http://localhost/?p=1"
    },
    "modified": "2019-07-05T09:23:31",
    "modified_gmt": "2019-07-05T12:23:31",
    "slug": "ola-mundo",
    "status": "publish",
    "type": "post",
    "link": "http://localhost/ola-mundo/",
    "title": {
      "rendered": "Olá, mundo!"
    },
    "content": {
      "rendered": "\n<p>Boas-vindas ao WordPress. Esse é o seu primeiro post. Edite-o ou exclua-o, e então comece a escrever!</p>\n",
      "protected": false
    },
    "excerpt": {
      "rendered": "<p>Boas-vindas ao WordPress. Esse é o seu primeiro post. Edite-o ou exclua-o, e então comece a escrever!</p>\n",
      "protected": false
    },
    "author": 1,
    "featured_media": 0,
    ...
    "categories": [
      1
    ],
    "tags": [],
    ...
  }
]

Se você estiver usando URLs amigáveis (lá no Painel, em Configurações →Links permanentes), você pode acessar http://localhost/wp-json/wp/v2/posts para obter o mesmo resultado.

O que está acontecendo aqui?

Quando você digitou o endereço e apertou enter, o seu navegador fez uma requisição para o servidor (localhost, neste caso), através do protocolo HTTP usando o método, que também pode ser chamado de verbo, GET. Sim, é o mesmo GET que a gente coloca no atributo method dos formulários. Resumindo, uma solicitação GET através do protocolo HTTP. Você usa isso todo dia, porque é assim que a internet funciona. Na verdade é assim que a World Wide Web funciona, porque internet é a rede que conecta os computadores, mas essa diferença fica pra outro texto.

Como usar a API REST do WordPress

Como a API REST se baseia em uma comunicação cliente/servidor, existem dois cenários, dependendo de que lado da comunicação você está. Se você é o cliente, você pode usar a API com qualquer linguagem de programação que consiga se comunicar por HTTP. Se você é o servidor, são grandes as chances do WordPress já implementar o que você precisa. Caso contrário, é só criar um endpoint novo.

Cliente: consumindo dados de sites WP externos

Se você quer consumir os dados da API REST de uma outra instalação do WordPress, externa à sua, tudo o que você tem que fazer é… uma solicitação GET através do protocolo HTTP. O WP tem algumas funções nativas que podem ajudar a fazer isso de forma bem fácil. O código abaixo usa a função nativa wp_remote_get() para consumir a API de demonstração do WordPress. O fato de estarmos usando um WordPress para consumir dados da API REST de outro WordPress é pura conveniência. No mundo real, este código poderia estar em qualquer linguagem ou framework.

PHP
// Faz a solicitação GET para o endereço.
$request = wp_remote_get( 'http://demo.wp-api.org/wp-json/wp/v2/posts' );
// Se não houve erro...
if ( ! is_wp_error( $request ) ) {
    // pegamos o "corpo" da resposta recebida...
    $body = wp_remote_retrieve_body( $request );
    // e transformamos de JSON em um array PHP normal.
    $data = json_decode( $body );

    // Se não houve erro nesta etapa, iteramos pelo array
    // e montamos uma lista com título e link.
    if ( ! is_wp_error( $data ) ) {
	    echo '<ul>';
	    foreach( $data as $rest_post ) {
		    echo '<li>';
			    echo '<a href="' . esc_url( $rest_post->link ) . '">' . $rest_post->title->rendered . '</a>';
		    echo '</li>';
	    }
	    echo '</ul>';
    }
}

Cliente: enviando dados para sites WP externos

Se você precisa enviar um dado para que ele seja gravado no site WordPress externo é preciso dar um passo a mais. Isso acontece por dois motivos:

  • Você precisa provar que é um usuário WP com permissões para isso e
  • O método GET é usado para obter dados. Para enviar é preciso usar outro verbo, como o POST, por exemplo.

Nativamente, o WordPress só dá conta de autenticações por cookie, então você vai precisar estar conectado ao site na sua máquina e a integração precisa ser feita no lado do cliente através de JavaScript. Quase sempre esse não é o cenário que você tem na mão.

A documentação oficial indica alguns plugins que ajudam na autenticação. O mais simples para começar é o Basic-Auth, mas atenção: com esse plugin o usuário e senha é enviado em todas as requisições, por isso só use o Basic-Auth para testes ou em sites com HTTPS.

Depois de baixar e ativar o plugin, você pode usar um código como este para criar um novo post. Veja os dados de autenticação e o uso da função nativa wp_remote_post(). A lista completa de atributos que você pode passar no corpo da requisição (o parâmetro body) está na documentação oficial.

PHP
$username = 'admin'; // Não use admin/admin em produção!
$password = 'admin';
$response = wp_remote_post(
    'http://localhost/wp-json/wp/v2/posts',
    [
        'headers' => [
            'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ),
        ],
        'body'    => [
            'title'   => 'Meu novo post',
            'content' => 'Texto do post',
        ],
    ]
);

Para servidores em produção, o ideal é evitar esse usuário e senha indo e vindo toda hora. Por isso, o recomendável é usar um plugin como o JWT Authentication for WP REST API. Depois de autenticar o usuário, ele gera um token.

Servidor: disponibilizando dados do seu site WordPress para sites externos

Por padrão, o WordPress já fornece muitos endpoints (veja a parte de Conceitos e definições para saber mais) e existem alguns que ainda não estão na documentação, como o /wp/v2/search. Para habilitar a API REST para o seu Custom Post Type basta colocar 'show_in_rest' => true nos argumentos passados para a função register_post_type(). Se o CPT é registrado por outro plugin ou pelo tema (mesmo isso sendo território dos plugins), você pode alterar os argumentos usando o filtro register_post_type_args.

Se o que você precisa vai além do fornecido pelo próprio WordPress, é só usar a action rest_api_init e a função register_rest_route(). Esta página da documentação explica passo a passo o que é preciso fazer, mas basicamente você vai criar um código parecido com este abaixo e implementar essa função minha_funcao(), que será a responsável pelo recebimento e/ou envio dos dados. O parâmetro aceita qualquer callable, um conceito que eu expliquei neste vídeo.

PHP
add_action(
    'rest_api_init',
    function () {
        register_rest_route(
            'meuplugin/v1',
            '/autor/(?P<id>\d+)',
            array(
              'methods' => 'GET',
              'callback' => 'minha_funcao', // Esse callable será chamado para responder as chamadas para '/wp-json/meuplugin/v1/autor/<id>'.
            )
        );
    }
);

O primeiro argumento de register_rest_route() é o namespace e o segundo é a rota (ou route). Vamos para a seção de Conceitos e definições, porque saber o que é cada uma dessas coisas facilita (muito) o entendimento da documentação.

Conceitos e definições de REST

Começando do começo, para entender o que é a API REST vamos precisar entender o que é Interface, o I de API.

O que é Interface?

Uma interface é a camada externa de alguma coisa, que aceita entradas e fornece saídas (inputs e outputs). Sim, é um conceito extremamente amplo, mas é isso aí mesmo. Exemplos de interfaces são o seu teclado, seu monitor, as telas do seu site e as tomadas da sua casa.

O conceito de interface está diretamente relacionado ao conceito de caixa-preta: Não importa como a coisa é implementada, desde que dada uma determinada entrada, a saída seja a esperada.

Então não importa a cor dos fios que levam a eletricidade até a tomada, o que importa é funcionar quando plugar seu aparelho lá. Da mesma forma, não importa como está implementado o backend de uma tela, o que importa é acontecer o que se espera quando um botão é apertado.

O “não importa” aqui é só para o conceito de caixa-preta, ok? Como profissional WordPress, a forma como o WP implementa as coisas deve importar e muito para você.

E o que é uma API?

API é o acrônimo de Application Programming Interface, ou seja, Interface de Programação de Aplicação. Se você for como eu, essas siglas raramente dizem alguma coisa de útil. Neste caso, seu site WordPress, por exemplo, é uma aplicação, que tem uma interface acessível através de programação.

Quando você chama qualquer função nativa do WordPress, “não importa” como aquela função foi implementada, o que importa é que ela faça o que se espera. Se eu chamar wp_insert_post() com os parâmetros certos, eu não estou interessado em como o WP vai processar isso, eu só quero ter certeza de que o post vai ser criado. Então, usando programação, estou fornecendo um input e espero o output correto.

Tem um post aqui no blog falando mais detalhes sobre o que é uma API.

O que é REST?

Se você já viu algum desenho animado, sabe que o R de R.I.P. é Rest e quer dizer descansar. O REST da API não tem absolutamente nada a ver com isso (e esse é um dos motivos para sempre escrever em letras maiúsculas).

REST neste caso vem de REpresentational State Transfer, ou seja, Transferência de Estado Representacional. Se a sigla de API não queria dizer muito, essa então não diz nada.

A explicação é a seguinte: dado um recurso, como posts, páginas, usuários, categorias, etc., criamos uma representação textual do estado atual deste recurso. Qual é o título e texto do post ou o nome de um usuário são atributos que formam esse “estado atual” do recurso e colocando isso em um JSON temos uma representação textual. REST é a transferência destas representações do estado de um recurso ou, como na sigla, de um estado representacional.

E RESTful?

Sabe peaceful, helpful, painful e careful? Então, o sufixo -ful em inglês indica a qualidade de alguma coisa. Peaceful é aquilo que dá paz (peace), helpful é aquilo que fornece ajuda (help) e assim por diante, mais ou menos como o nosso -oso nas palavras doloroso e cuidadoso.

RESTful então é tudo aquilo que implementa a arquitetura REST, só isso. Se um site tem API REST, o site é RESTful. Mais uma daquelas pegadinhas como design e designer.

Cuidado para não usar REST full ou RESTfull. Full em inglês quer dizer cheio ou completo e não tem nenhuma ligação com o que a gente está falando aqui.

Namespace, routes, endpoints e schemas

Existe um glossário na documentação, já que você pode esbarrar em algumas palavras novas durante o desenvolvimento. Eu vou deixar aqui a explicação de algumas dessas palavras para facilitar. Se houver alguma que eu não expliquei e você sentiu falta, deixe nos comentários que eu atualizo o texto.

Namespace

Nesse caso é uma string que vai isolar as funcionalidades por grupos. O namespace padrão é wp/v2, o WooCommerce atualmente usa wc/v3 e você pode usar cliente/v1 ou plugin/v1, variando o v1 conforme o progresso e publicação do código. É o primeiro parâmetro que você passa ao registrar uma nova route com a função register_rest_route().

Routes e endpoints

Uma rota ou uma route é o segundo parâmetro passado para register_rest_route(). Ela é a string que disponibiliza uma funcionalidade e pode ter um ou mais endpoints associados a ela.

Um exemplo, tirado da documentação, é o endereço http://example.com/wp-json/wp/v2/posts/123. Nele existe apenas uma rota, que é wp/v2/posts/123. Esta mesma rota, dependendo do verbo/método utilizado na requisição, tem 3 endpoints:

  • Se você usar GET vai receber como retorno os dados de um post, fornecido pelo método get_item;
  • Se usar o verbo POST ou o verbo PUT, você pode atualizar um post. O método update_item vai ser usado neste caso e
  • Se usar o verbo DELETE o post será excluído pelo método delete_item.

Ou seja, essa mesma rota expõe três endpoints, que você acessa dependendo do método/verbo utilizado na requisição. Você pode ver mais sobre esse caso olhando o método register_routes() da classe WP_REST_Posts_Controller.

No texto eu usei wp_remote_get() e wp_remote_post(), mas você pode usa a função wp_remote_request() passando um verbo qualquer através do parâmetro method.

Schema

Um esquema, ou schema, é a representação dos dados que formam a resposta da API. O schema de Posts diz que os campos id, title, content, author, etc., farão parte da resposta fornecida API. Esses dados são úteis tanto para humanos que precisam criar uma integração com a API como para integrações automatizadas.

Para ter acesso ao esquema, é só enviar uma requisição para o endereço usando o método OPTIONS. Enquanto o navegador é ótimo para fazer requisições GET, nem sempre é tão fácil testar requisições com esses verbos mais “incomuns”. Para isso eu recomendo o programa Postman, disponível para Linux, Windows e Mac. De forma muito simples, ele permite que você formate a requisição como precisar, alterando verbo, corpo e cabeçalhos.


Gostou? Não esquece de comentar e compartilhar!

Este post tem 24 comentários

  1. Tiago França

    Olá,
    Excelente artigo.
    Gostaria de fazer uma pergunta sobre limitar posts.
    Como faço pra paginar o retorno?
    Desde já, obrigado.

  2. Sérgio santiago

    Olá, tenho uma aplicação feita em gatsby que precisa consumir dados de uma página WordPress, porém não consigo obter retorno da chamada para minha pagina, apenas para outros endereços, seria alguma configuração da minha pagina no WordPress?

    1. Felipe Elia

      Dá algum erro específico, Sérgio?

  3. Geone Castro

    Ótima matéria, porém tenho necessito de um básico exemplo, só preciso de um exemplo de como alterar o retorno do json da api rest.. digamos como exemplo (situação tomada com o exemplo), no cabeçario do pedido me retornar apenas 2 campos…e por exemplo sendo 1 deles o id_ped e gostaria ainda que viesse codigo_do_pedido ao invés de id_ped….só um básico exemplo…agradeço

  4. Renan

    Fala Felipe, beleza?
    Então, eu tenho um site estático em html e preciso integrar com um blog externo pra pegar os ultimos 3 posts com o thumbnail, title e link.

    Tentei até fazer um teste via Ajax abaixo com o feed do blog, mas dá erro de CORS policy: No ‘Access-Control-Allow-Origin’.
    $(function () {
    $.ajax({
    url: ‘https:blog.mobills.com.br/feed/’,
    type: ‘GET’,
    dataType: ‘json’,
    success: function (json) {
    console.log(json);
    }
    });
    });

    OBS: Até consegui buscar utilizando o DOM do PHP, mas a premissa aqui do projeto é não utilizar PHP para requisição.

    Já fez algo parecido?

    1. Felipe Elia

      Oi Renan, ao invés de usar https//:blog.mobills.com.br/feed/ já tentou usar o endereço que eu deixei no texto e comentei no vídeo?

  5. Israel

    Boa noite, ótima matéria! Eu estou “tentando” integrar um aplicativo com um site wp já existente, eu precisava pegar uma parte específica desse site, que não é um post nem uma página. Depois do wp/v2/ tem algo que dê pra fazer a chamada? No caso é uma listagem de imóveis, e no meu site ele traz esses imóveis na rota https://meusite.com.br/servicos/venda… precisava fazer o get e mostrar no app. Desde já agradeço!

    1. Felipe Elia

      Oi Israel. Você vai ter que ver se esses imóveis são um Custom Post Type do WordPress e, se forem, ver se eles estão expostos na API REST. Os CPTs são registrados usando a função register_post_type() e nessa função há o parâmetro “show_in_rest”, que deve estar como true para você conseguir fazer o que precisa. Espero ter ajudado. Abraços!

      1. Israel

        Boa noite!! Muito obrigado pelo retorno, eu consegui fazer o get! O caminho que eu precisava colocar após o /v2/ pra buscar era “properties”, com isso consigo trazer todos os imóveis (com texto e imagem destacada) e através do ID eu consigo abrir um imóvel específico. E agora o meu problema é outro! heheh… Eu quero pegar a galeria de imagens do imóvel que estiver em destaque, caso tenha alguma dica eu agradeço muito, estou batendo a cabeça com isso agora, tentei algumas alternativas (como chamar o site dentro do app utilizando iframe, mas não é viável e deixa muito lento também), mas quero mesmo conseguir buscar a galeria e mostrar com slides dentro do app… Mais uma vez muito obrigado pelo retorno!! Abraço!

        1. Felipe Elia

          Ih rapaz, aí complicou. Se esses dados não estão sendo expostos pela API REST você vai precisar alterar o código para que eles passem a ser, caso contrário não tem jeito. Abraços!

          1. Israel

            Bom dia, estou estudando os arquivos do template que estou usando pra faze a alteração, assim que eu descobrir compartilho aqui como foi! hehe.. Muito obrigado mais uma vez. Abraços.

  6. Bárbara

    Olá Felipe, tudo bem? A minha dúvida é a seguinte, tenho um laboratório de analises clinicas como cliente e estou formulando um novo site para ele em wordpress, porém será preciso integrar a ferramenta worklab onde eles colocam os resultados de exames online para os pacientes pegarem com o site novo em wordpress. Na certa faria essa integração através de API… queria uma dica de como proceder, de onde partir para conseguir fazer essa integração. Adorei o conteúdo, muito bom!

    1. Felipe Elia

      Oi Bárbara, nesse caso você vai consumir a API do worklab, a REST do WP infelizmente não vai ajudar. Você vai precisar pegar a documentação da API com eles e fazer as chamadas conforme o necessário. Para as chamadas você pode usar as funções wp_remote_get() e wp_remote_post() que eu comentei no texto, elas costumam ajudar bastante. Boa sorte!

  7. Jesley

    Salve meu caro, estou tentando achar uma solução para uma questão que tenho, mas sequer estou sabendo como pesquisar, é o seguinte, eu tenho um site no wordpress e vou cadastrar vendedores dentro de uma intranet nesse meu site wordpress, porem alem de disponibilizar tabelas dentro de uma pagina especifica para cada vendedor, eu tenho um serviço de consulta cpf de outro site, eu pago esse serviço por apenas um usuario, o que eu gostaria de fazer é integrar esse site com minhas credenciais logando automaticamente dentro do meu site através de um iframe ou outra solução (imagino que contaria como um usuario unico ja que a identificação é por IP) e assim os vendedores usarem esse sistema de busca internamente na intranet do meu site wordpress. É possivel fazer algo assim, e qual o caminho se a resposta for sim. Grato.

    1. Felipe Elia

      Oi Jesley, seria preciso ver se isso é possível no serviço externo primeiro, tanto na questão de código/funcionamento quanto na sua questão contratual com eles. O ideal é entrar em contato com o pessoal desse serviço e pedir a documentação da API se existir e partir daí. Boa sorte! Abraços

  8. Fernando

    fala man blz? Estou com 2 sites iguais um no domínio normal outro no subdomínio preciso fazer que os 2 conversem automáticamente. É um site de eventos, todos dados de um precisa ser sincronizado no outro em ambos os site. esse post seu sera que me ajuda?

  9. w

    Ótimo conteúdo.

  10. Leonardo Santana Correa

    Também estou com o mesmo problema

    1. Felipe Elia

      Você chegou a ver a pergunta que eu fiz sobre o problema? “Você consegue usar o editor de blocos para gerenciar seus posts ou dá algum erro?”

  11. Kanitar Oberst

    Olá, eu estou com um problema no meu wordpress relacionado ao API REST, e não consigo resolver. Sempre que faço um diagnóstico no wordpress, aparece:
    A API REST NÃO SE COMPORTOU CORRETAMENTE

    A API REST é uma forma como o WordPress, e outras aplicações, se comunicam com o servidor. Um exemplo é a tela do editor de blocos, que depende da API para exibir e salvar seus posts e páginas.

    A API REST não processou corretamente o parâmetro context da consulta.

    Como consigo resolver este problema ??

    1. Felipe Elia

      Isso pode acontecer por vários motivos. Um deles pode ser algum plugin de segurança barrando a API REST de funcionar. Você consegue usar o editor de blocos para gerenciar seus posts ou dá algum erro?

Os comentários estão encerrados.