{"id":233937,"date":"2023-02-25T18:16:00","date_gmt":"2023-02-25T15:16:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233937"},"modified":"2022-11-11T13:17:10","modified_gmt":"2022-11-11T10:17:10","slug":"guia-detalhado-na-criacao-e-busca-de-endpoints-personalizados-da-api-rest-wp","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/guia-detalhado-na-criacao-e-busca-de-endpoints-personalizados-da-api-rest-wp\/","title":{"rendered":"Guia detalhado na cria\u00e7\u00e3o e busca de endpoints personalizados da API REST WP"},"content":{"rendered":"\n<p>Esta postagem mostrar\u00e1 como criar endpoints REST personalizados do WordPress e diferentes m\u00e9todos para realizar solicita\u00e7\u00f5es a eles. Haver\u00e1 exemplos em PHP, jQuery e Javascript vanilla.<\/p>\n<p>Suponho que voc\u00ea j\u00e1 esteja familiarizado com o que \u00e9 WP REST API, mas aqui est\u00e1 um breve resumo. A API REST do WordPress \u00e9 uma interface JSON para enviar e receber dados do seu site WordPress. Voc\u00ea pode acessar os endpoints (caminhos\/URLs espec\u00edficos) tanto externa quanto internamente. O WordPress j\u00e1 tem v\u00e1rios endpoints dispon\u00edveis, por exemplo, para buscar posts, categorias, pesquisar no site e muito mais. Veja uma <a href=\"https:\/\/developer.wordpress.org\/rest-api\/reference\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">vis\u00e3o geral dos endpoints padr\u00e3o do WordPress<\/a> aqui. Mas os desenvolvedores s\u00e3o totalmente livres para criar seus pr\u00f3prios endpoints personalizados usando esta API, seja para realizar a\u00e7\u00f5es ou buscar dados.<\/p>\n<p>Come\u00e7aremos com o primeiro passo; que est\u00e1 criando endpoints personalizados. Se voc\u00ea est\u00e1 interessado apenas em como fazer solicita\u00e7\u00f5es, pule para a segunda parte.<\/p>\n<h2>Criar endpoints personalizados<\/h2>\n<p>O registro de endpoints personalizados \u00e9 feito em PHP. Voc\u00ea pode adicionar o c\u00f3digo ao arquivo de c\u00f3digo do seu tema <code>functions.php<\/code>ou de um plugin ativo. Fa\u00e7a uma fun\u00e7\u00e3o vinculada <code>rest_api_init<\/code>e use a fun\u00e7\u00e3o <code>[register_rest_route](https:\/\/developer.wordpress.org\/reference\/functions\/register_rest_route\/)()<\/code>para cada endpoint que voc\u00ea gostaria de adicionar.<\/p>\n<p>Como primeiro par\u00e2metro, <code>register_rest_route()<\/code>voc\u00ea precisa fornecer um namespace exclusivo para garantir que seus endpoints n\u00e3o entrem em conflito com nenhum outro. Use o slug do seu tema ou plugin. \u00c9 uma pr\u00e1tica comum incluir um <code>\/<\/code>seguido de um n\u00famero de vers\u00e3o para seu c\u00f3digo. Como exemplo, usarei o namespace <code>awhitepixel\/v1<\/code>. O segundo par\u00e2metro \u00e9 o caminho (que segue o namespace). Finalmente, voc\u00ea pode opcionalmente fornecer uma matriz como terceiro par\u00e2metro com op\u00e7\u00f5es. Nesta matriz voc\u00ea pode, por exemplo, definir o m\u00e9todo de solicita\u00e7\u00e3o (GET, POST ou qualquer outro), definir par\u00e2metros e, mais importante, definir a fun\u00e7\u00e3o a ser executada quando esse endpoint for solicitado.<\/p>\n<p>No m\u00ednimo, voc\u00ea deve fornecer os argumentos &#8216;m\u00e9todo&#8217; e &#8216;retorno de chamada&#8217; (que \u00e9 a fun\u00e7\u00e3o para lidar com os dados do terminal) como terceiro par\u00e2metro. Para &#8216;m\u00e9todo&#8217; voc\u00ea pode defini-los como &#8216; <code>GET'<\/code>, <code>'POST'<\/code>, <code>'PUT'<\/code>, ou qualquer outro m\u00e9todo de solicita\u00e7\u00e3o v\u00e1lido (ou uma matriz de v\u00e1rios), mas eu recomendo usar os padr\u00f5es do WordPress para isso. Eles s\u00e3o os seguintes:<\/p>\n<ul>\n<li><code>WP_REST_Server::READABLE<\/code> m\u00e9todo &#8216; <code>GET<\/code>&#8216;<\/li>\n<li><code>WP_REST_Server::EDITABLE<\/code> m\u00e9todos &#8216; <code>POST<\/code>&#8216;, &#8216; <code>PUT<\/code>&#8216; e &#8216; <code>PATCH<\/code>&#8216;<\/li>\n<li><code>WP_REST_Server::DELETABLE<\/code> m\u00e9todo &#8216; <code>DELETE<\/code>&#8216;<\/li>\n<li><code>WP_REST_Server::ALLMETHODS<\/code> todos os m\u00e9todos acima<\/li>\n<\/ul>\n<p>Vamos criar um endpoint personalizado b\u00e1sico que pode ser alcan\u00e7ado usando solicita\u00e7\u00f5es GET:<\/p>\n<pre><code>add_action( 'rest_api_init', function() {\n    register_rest_route( 'awhitepixel\/v1', '\/getsomedata', [\n        'method'   =&gt; WP_REST_Server::READABLE,\n        'callback' =&gt; 'awhitepixel_rest_route_getsomedata',\n    ] );\n} );<\/code><\/pre>\n<p>Na linha <code>#2<\/code>, definimos nosso endpoint personalizado como &#8216; <code>awhitepixel\/v1\/getsomedata<\/code>&#8216;. O URL completo seria o URL raiz da API REST do WordPress prefixado, que \u00e9 <code>&lt;yourdomain&gt;\/wp-json<\/code>. Portanto, a URL completa para o endpoint acima seria &#8216; <code>&lt;yourdomain&gt;\/wp-json\/awhitepixel\/v1\/getsomedata<\/code>&#8216;. Na linha <code>#4<\/code>, fornecemos um nome de fun\u00e7\u00e3o como retorno de chamada, que adicionaremos em breve.<\/p>\n<p>Ao registrar (ou alterar) as rotas da API REST usando <code>register_rest_route()<\/code>, voc\u00ea precisar\u00e1 <strong>liberar seus permalinks<\/strong> para que funcione. Voc\u00ea pode fazer isso visitando Configura\u00e7\u00f5es&gt; Permalinks no admin e simplesmente clique em Salvar.<\/p>\n<p>Ainda n\u00e3o definimos a fun\u00e7\u00e3o callback \u2013 que \u00e9 a fun\u00e7\u00e3o para o c\u00f3digo que trata da rea\u00e7\u00e3o de usar esse endpoint. Ele deve retornar uma resposta v\u00e1lida REST (em JSON), portanto, voc\u00ea precisar\u00e1 retornar algo, mesmo que o endpoint n\u00e3o deva retornar dados. Voc\u00ea pode usar a fun\u00e7\u00e3o <code>[rest_ensure_response](https:\/\/developer.wordpress.org\/reference\/functions\/rest_ensure_response\/)()<\/code>function ou criar uma inst\u00e2ncia de <code>WP_REST_Response<\/code>objeto como retorno do callback. Como par\u00e2metro para a fun\u00e7\u00e3o de retorno de chamada, obtemos um <code>WP_REST_Request<\/code>objeto que cont\u00e9m todas as informa\u00e7\u00f5es sobre a solicita\u00e7\u00e3o \u2013 incluindo quaisquer par\u00e2metros. Vamos criar uma fun\u00e7\u00e3o de callback simples que simplesmente envia algum texto como resposta:<\/p>\n<pre><code>function awhitepixel_rest_route_getsomedata( $request) {\n    $response = 'Hello there!';\n    return rest_ensure_response( $response );\n}<\/code><\/pre>\n<p>Esta \u00e9 a maneira mais b\u00e1sica de escrever um retorno de chamada. A fun\u00e7\u00e3o <code>rest_ensure_response()<\/code>garante que todos os dados que fornecemos (a string) sejam convertidos em uma resposta v\u00e1lida REST. Obviamente voc\u00ea vai querer adicionar mais c\u00f3digo aqui, para fazer algo no WordPress ou buscar e enviar dados de volta.<\/p>\n<p>Com o c\u00f3digo acima (registrando o endpoint e a fun\u00e7\u00e3o de retorno de chamada), voc\u00ea pode tentar acessar a URL em seu navegador e ver o que obt\u00e9m. (Lembre-se de liberar seus permalinks). Acessar <code>&lt;domain&gt;\/wp-json\/awhitepixel\/v1\/getsomedata<\/code>no navegador mostrar\u00e1 a string &#8220;Hello there!&quot;.<\/p>\n<h3>Aceitando par\u00e2metros<\/h3>\n<p>\u00c9 muito comum e \u00fatil permitir que os endpoints aceitem par\u00e2metros. Por exemplo, se o seu site tiver, por exemplo, dados do produto, voc\u00ea desejar\u00e1 um endpoint no qual possa fornecer um ID do produto para obter os dados desse produto. H\u00e1 duas maneiras de fazer isso. A maneira mais comum \u00e9 usar a string de consulta GET (que s\u00e3o anexadas ap\u00f3s a URL ap\u00f3s um <code>?<\/code>, separadas por <code>&amp;<\/code>no formato key=value. Por exemplo, &#8216; <code>&lt;endpoint&gt;\/product\/?product_id=14<\/code>&#8216;). Alternativamente, voc\u00ea pode definir um padr\u00e3o de URL &#8220;mais bonito&#8221;, onde os par\u00e2metros fazem parte do caminho. Por exemplo &#8216; <code>&lt;endpoint&gt;\/product\/14\/<\/code>&#8216;. Este \u00faltimo m\u00e9todo requer algum conhecimento de regexes. Qual m\u00e9todo voc\u00ea vai escolher depende de voc\u00ea, vou demonstrar os dois abaixo.<\/p>\n<h4>Par\u00e2metros GET<\/h4>\n<p>Definir poss\u00edveis par\u00e2metros GET para seu endpoint \u00e9 usar a <code>args<\/code>chave &#8216; &#8216; no <code>register_rest_route()<\/code>terceiro par\u00e2metro de. Para cada par\u00e2metro que voc\u00ea deseja permitir, defina o valor da chave (no exemplo acima &#8216; <code>product_id<\/code>&#8216;) e uma matriz de op\u00e7\u00f5es para esse par\u00e2metro. Como op\u00e7\u00f5es, voc\u00ea pode definir o formato do par\u00e2metro (se espera, por exemplo, um n\u00famero ou uma string) e tamb\u00e9m decidir se esse par\u00e2metro \u00e9 obrigat\u00f3rio ou n\u00e3o.<\/p>\n<p>Como exemplo, queremos permitir que nosso endpoint aceite &#8216; <code>product_id<\/code>&#8216; como um n\u00famero n\u00e3o obrigat\u00f3rio.<\/p>\n<pre><code>add_action( 'rest_api_init', function() {\n    register_rest_route( 'awhitepixel\/v1', '\/getsomedata', [\n        'method'   =&gt; WP_REST_Server::READABLE,\n        'callback' =&gt; 'awhitepixel_rest_route_getsomedata',\n        'args'     =&gt; [\n            'product_id' =&gt; [\n                'required' =&gt; false,\n                'type'     =&gt; 'number',\n            ],\n        ],\n    ] );\n} );\n\u00a0\nfunction awhitepixel_rest_route_getsomedata( $request) {\n    $product_id = $request-&gt;get_param( 'product_id' );\n    if (! empty( $product_id)) {\n        $response = 'Return product data for ID '. $product_id;\n    } else {\n        $response = 'Hello there!';\n    }\n    return rest_ensure_response( $response );\n}<\/code><\/pre>\n<p>Se voc\u00ea definir um par\u00e2metro como true em <code>required<\/code>, o WordPress lidar\u00e1 com a devolu\u00e7\u00e3o de uma resposta de erro 400. Da mesma forma se voc\u00ea passar um formato inv\u00e1lido, por exemplo &#8220;hello&#8221; como valor para um par\u00e2metro que espera um n\u00famero.<\/p>\n<p>Na linha <code>#15<\/code>da fun\u00e7\u00e3o de retorno de chamada, voc\u00ea v\u00ea como obter o valor do par\u00e2metro da solicita\u00e7\u00e3o; usando o m\u00e9todo no objeto <code>get_param()<\/code>passado. <code>WP_REST_Request<\/code>A t\u00edtulo de exemplo, mostrarei diferentes respostas dependendo se <code>product_id<\/code>foram fornecidas ou n\u00e3o (lembre-se que definimos como opcional). A l\u00f3gica de modificar seu c\u00f3digo de acordo com os par\u00e2metros fornecidos fica totalmente a seu crit\u00e9rio e do seu projeto. Voc\u00ea pode ter menos endpoints que aceitem muitos par\u00e2metros ou muito mais endpoints separados para cada caso espec\u00edfico.<\/p>\n<p>Com o c\u00f3digo acima, obterei &quot;Ol\u00e1!&quot; quando visito <code>&lt;yourdomain&gt;\/awhitepixel\/v1\/getsomedata<\/code>e &quot;Retornar dados do produto para ID 14&quot; quando vou para <code>&lt;yourdomain&gt;\/awhitepixel\/v1\/getsomedata\/?product_id=14<\/code>.<\/p>\n<h4>Par\u00e2metros como parte do caminho<\/h4>\n<p>Se voc\u00ea quiser permitir que os par\u00e2metros fa\u00e7am parte do caminho em vez de GET string de consulta, voc\u00ea pode fazer isso. Voc\u00ea ent\u00e3o fornecer\u00e1 um padr\u00e3o regex no caminho \u2013 o segundo par\u00e2metro para <code>register_rest_route()<\/code>.<\/p>\n<p>A cria\u00e7\u00e3o de padr\u00f5es regex pode parecer bastante enigm\u00e1tica, mas como \u00e9 um t\u00f3pico inteiro, voc\u00ea encontrar\u00e1 facilmente exemplos para casos espec\u00edficos se pesquisar no Google. Mostrarei um exemplo de defini\u00e7\u00e3o de uma regex que aceita um n\u00famero de qualquer tamanho;<\/p>\n<pre><code>add_action( 'rest_api_init', function() {\n    register_rest_route( 'awhitepixel\/v1', '\/getsomedata\/(?P&lt;product_id&gt;[d]+)', [\n        'method'   =&gt; WP_REST_Server::READABLE,\n        'callback' =&gt; 'awhitepixel_rest_route_getsomedata',\n    ] );\n} );\n\u00a0\nfunction awhitepixel_rest_route_getsomedata( $request) {\n    $product_id = $request-&gt;get_param( 'product_id' );\n    $response   = 'Return product data for ID '. $product_id;\n    return rest_ensure_response( $response );\n}<\/code><\/pre>\n<p>Como voc\u00ea pode ver na linha #2, adicionei o padr\u00e3o regex <code>(?P&lt;product_id&gt;[d]+)<\/code>no final. Esses padr\u00f5es significam que devemos coletar um n\u00famero (<code>d<\/code>) de qualquer comprimento (<code>+<\/code>) e atribuir o valor coletado \u00e0 chave de par\u00e2metro <code>product_id<\/code>. E em nossa fun\u00e7\u00e3o de retorno de chamada, usamos exatamente o mesmo m\u00e9todo que usamos ao configurar os par\u00e2metros GET; <code>get_param()<\/code>no <code>WP_REST_Request<\/code>objeto fornecido para a fun\u00e7\u00e3o.<\/p>\n<p>Com o c\u00f3digo acima (ap\u00f3s liberar os permalinks), podemos visitar a URL <code>&lt;yourdomain&gt;\/wp-json\/awhitepixel\/v1\/getsomedata\/14<\/code>para obter nossa resposta. Esse m\u00e9todo certamente resulta em URLs &#8220;mais bonitas&#8221;, mas o c\u00f3digo pode facilmente ficar mais dif\u00edcil de ler e corrigir bugs. Qualquer m\u00e9todo que voc\u00ea escolher \u00e9 com voc\u00ea.<\/p>\n<h3>Retornando a resposta adequada<\/h3>\n<p>Anteriormente, mencionei brevemente como a fun\u00e7\u00e3o de retorno de chamada precisa retornar uma resposta REST adequada. At\u00e9 agora, usamos o mais simples <code>rest_ensure_response()<\/code>. Mas \u00e0s vezes voc\u00ea pode querer mais controle do retorno do seu endpoint. Voc\u00ea pode, por exemplo, querer controlar o <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Status\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">c\u00f3digo de status de resposta HTTP<\/a>. Digamos que voc\u00ea esteja criando um endpoint no qual pode fornecer uma ID de produto e obter dados para esse produto. Mas se esse ID do produto n\u00e3o existir ou qualquer outro par\u00e2metro causar confus\u00e3o, talvez voc\u00ea queira retornar um c\u00f3digo de status de, por exemplo, 400 (solicita\u00e7\u00e3o inv\u00e1lida) ou 404 (n\u00e3o encontrado). Ou talvez 500 (erro do servidor). Sempre passar 200 (Sucesso) mesmo que a requisi\u00e7\u00e3o tenha sido ruim pode causar problemas no final do remetente.<\/p>\n<p>Eu recomendaria ent\u00e3o sua fun\u00e7\u00e3o de retorno de chamada retornando um <code>WP_REST_Response<\/code>objeto. Com este objeto voc\u00ea pode controlar v\u00e1rias coisas, incluindo o c\u00f3digo de status. \u00c9 mais f\u00e1cil do que voc\u00ea pensa! Na forma mais simples, voc\u00ea criaria uma nova inst\u00e2ncia de <code>WP_REST_Response<\/code>, forneceria uma matriz dos dados a serem retornados como primeiro par\u00e2metro e o c\u00f3digo de status como segundo par\u00e2metro. Como um exemplo:<\/p>\n<pre><code>function awhitepixel_rest_route_getsomedata( $request) {\n    $product_id = $request-&gt;get_param( 'product_id' );\n    \/\/ Do some external function call that returns product data or empty array on error\n    $product_data = awhitepixel_get_product( $product_id );\n    if (empty( $product_data)) {\n        return new WP_REST_Response( [\n            'message' =&gt; 'Product was not found',\n        ], 400 );\n    }\n    return new WP_REST_Response( $product_data, 200 );\n}<\/code><\/pre>\n<p>No exemplo acima armazenamos o retorno da <code>awhitepixel_get_product()<\/code>fun\u00e7\u00e3o em uma vari\u00e1vel. Esta fun\u00e7\u00e3o n\u00e3o existe, e voc\u00ea deve substitu\u00ed-la pela fun\u00e7\u00e3o que deve buscar (ou fazer) as a\u00e7\u00f5es que voc\u00ea deseja em seu projeto. Mas digamos que a fun\u00e7\u00e3o retorne uma matriz vazia e isso significa que algo deu errado (por exemplo, o produto n\u00e3o existia). Poder\u00edamos ent\u00e3o retornar um <code>WP_REST_Response<\/code>objeto com c\u00f3digo de status 400 e, opcionalmente, uma mensagem como dados explicando por que ele falhou (linha <code>#5-9<\/code>). Caso contr\u00e1rio, retornamos os dados com o c\u00f3digo de status 200 Success (linha <code>#10<\/code>).<\/p>\n<h2>Enviando solicita\u00e7\u00f5es para endpoints (personalizados)<\/h2>\n<p>Vamos para o outro lado, a parte de envio: como enviar solicita\u00e7\u00f5es para nossos endpoints personalizados. Normalmente voc\u00ea enviaria solicita\u00e7\u00f5es WP REST API usando Javascript e aqui voc\u00ea encontrar\u00e1 exemplos de uso de jQuery, biblioteca WordPress e Javascript vanilla. \u00c9 incomum, mas poss\u00edvel, executar uma solicita\u00e7\u00e3o REST com PHP tamb\u00e9m \u2013 ent\u00e3o inclu\u00ed um exemplo disso tamb\u00e9m.<\/p>\n<p>A primeira coisa a saber \u00e9 que voc\u00ea obviamente precisa saber o URL completo para enviar uma solicita\u00e7\u00e3o. Eu n\u00e3o recomendo codificar o dom\u00ednio (antes do endpoint), pois existem v\u00e1rias maneiras de obter isso se o seu Javascript estiver operando no WordPress. Em vers\u00f5es mais antigas do WordPress, voc\u00ea precisaria usar <code>[wp_localize_script](https:\/\/developer.wordpress.org\/reference\/functions\/wp_localize_script\/)()<\/code>em PHP e passar a URL REST principal como uma vari\u00e1vel Javascript global. Mas os exemplos abaixo mostram uma maneira mais nova e melhor de obter a URL raiz REST do site WordPress.<\/p>\n<p>Outra coisa a ser observada \u00e9 que, para o seu projeto, voc\u00ea provavelmente envolveria as solicita\u00e7\u00f5es como resultado de alguma a\u00e7\u00e3o. Para manter as coisas simples, estou preparando todas as solicita\u00e7\u00f5es no DOM, ent\u00e3o voc\u00ea deve certificar-se de incluir o c\u00f3digo da solicita\u00e7\u00e3o, por exemplo, como resultado de um visitante clicar em um bot\u00e3o.<\/p>\n<h3>Usando jQuery<\/h3>\n<p>Se voc\u00ea possui e deseja usar a biblioteca jQuery, pode usar sua <code>[$.ajax](https:\/\/api.jquery.com\/jquery.ajax\/)()<\/code>fun\u00e7\u00e3o.<\/p>\n<p>Mas primeiro uma nota sobre as depend\u00eancias do seu arquivo Javascript. Obviamente, seu script precisaria <code>'jquery'<\/code>como depend\u00eancia no enfileiramento. Mas para acessar facilmente a URL raiz REST do seu WordPress, adicione outra depend\u00eancia; &#8216;wp-api-request&#8217;. Isso garante que a vari\u00e1vel Javascript <code>wpApiSettings.root<\/code>esteja dispon\u00edvel e contenha a URL raiz da API REST. Aqui est\u00e1 um exemplo de como voc\u00ea enfileiraria seu script para ilustrar essa depend\u00eancia;<\/p>\n<pre><code>add_action( 'wp_enqueue_scripts', function() {\n    wp_enqueue_script(\n        'awp-javascript-wp-rest', \n        get_stylesheet_directory_uri(). '\/assets\/js\/javascript_wp_rest.js', \n        [ 'jquery', 'wp-api-request' ], \n        null, \n        true\n    );\n} );<\/code><\/pre>\n<p>A linha <code>#5<\/code>\u00e9 a mais interessante; onde definimos tanto jQuery quanto <code>wp-api-request<\/code>como depend\u00eancia. Ent\u00e3o, em nosso arquivo Javascript, podemos executar uma solicita\u00e7\u00e3o WP REST API da seguinte forma:<\/p>\n<pre><code>( function( $) {\n    \/\/ Send request\n    $.ajax( {\n        url: wpApiSettings.root + 'awhitepixel\/v1\/getsomedata',\n        method: 'GET',\n        data: {\n            product_id: 14\n        },\n        success: function( data) {\n            console.log( data );\n        }\n    } );\n} )( jQuery );<\/code><\/pre>\n<p>Isso \u00e9 o mais b\u00e1sico poss\u00edvel. Usamos <code>$.ajax()<\/code>para enviar uma solicita\u00e7\u00e3o GET para a url definida. Como URL, usamos <code>wpApiSettings.root<\/code>para obter a URL raiz da API REST e, em seguida, anexamos o endpoint desejado ap\u00f3s ela; no nosso caso, o endpoint personalizado que criamos anteriormente. Opcionalmente podemos passar par\u00e2metros em &#8216;data&#8217;. O exemplo acima passa <code>product_id<\/code>com o valor 14 para o endpoint. Finalmente, na <code>success<\/code>fun\u00e7\u00e3o, recebemos a solicita\u00e7\u00e3o (bem-sucedida) como par\u00e2metro e estamos livres para fazer o que quisermos com ela. No exemplo acima, n\u00f3s o imprimimos no console.<\/p>\n<h3>Usando a biblioteca do WordPress (n\u00e3o-jQuery)<\/h3>\n<p>Se o seu site WordPress n\u00e3o possui ou pode usar a biblioteca jQuery, voc\u00ea pode usar a biblioteca Javascript do WordPress para executar facilmente uma solicita\u00e7\u00e3o da API REST. A fun\u00e7\u00e3o \u00e9 que est\u00e1 dispon\u00edvel no namespace <code>apiFetch<\/code>global do WordPress. \u00e9 um m\u00e9todo wrapper para a fun\u00e7\u00e3o padr\u00e3o do navegador (que \u00e9 demonstrado a seguir).<code>wp``wp.apiFetch()``fetch()<\/code><\/p>\n<p>Nosso Javascript precisar\u00e1 da depend\u00eancia &#8216;wp-api&#8217; para usar wp.apiFetch(). Por exemplo, poder\u00edamos enfileirar o script assim:<\/p>\n<pre><code>add_action( 'wp_enqueue_scripts', function() {\n    wp_enqueue_script(\n        'javascript-wp-rest', \n        get_stylesheet_directory_uri(). '\/assets\/js\/javascript_wp_rest.js', \n        [ 'wp-api' ], \n        null, \n        true\n    );\n} );<\/code><\/pre>\n<p>Voc\u00ea encontrar\u00e1 a depend\u00eancia cr\u00edtica em line <code>#5<\/code>. Com isso, garantimos que nosso arquivo Javascript esteja <code>wp.apiFetch()<\/code>dispon\u00edvel. Aqui est\u00e1 um exemplo b\u00e1sico de como us\u00e1-lo:<\/p>\n<pre><code>function awpSendRequest() {\n    wp.apiFetch( {\n        path: 'awhitepixel\/v1\/getsomedata?product_id=14',\n    } ).then( data =&gt; {\n        console.log( data );\n    } );\n}\n\u00a0\nif (document.readyState != 'loading') {\n    awpSendRequest();\n} else {\n    document.addEventListener( 'DOMContentLoaded', awpSendRequest );\n}<\/code><\/pre>\n<p>Tenha em mente que as linhas <code>#9-13<\/code>s\u00e3o apenas l\u00f3gicas para executar a fun\u00e7\u00e3o depois que o DOM estiver pronto.<\/p>\n<p>Um benef\u00edcio de usar <code>wp.apiFetch()<\/code>sobre o normal <code>fetch()<\/code>\u00e9 que podemos usar &#8216;path&#8217; que requer apenas o endpoint, em vez de &#8216;url&#8217; que requer a URL completa. Outro benef\u00edcio \u00e9 que a primeira &#8220;cadeia&#8221; de <code>.then()<\/code>retorna os dados j\u00e1 formatados em JSON. Quando voc\u00ea usa o original <code>.fetch()<\/code>voc\u00ea precisa de mais cadeias &#8220;.then()&#8221;. D\u00ea uma olhada no pr\u00f3ximo exemplo (&#8220;Using vanilla Javascript&#8221;) para ver o que quero dizer.<\/p>\n<p>Tenha em mente que <code>fetch()<\/code>(e como consequ\u00eancia <code>wp.apiFetch()<\/code>) <a href=\"https:\/\/github.com\/github\/fetch\/issues\/256\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">n\u00e3o fornece uma maneira &#8220;limpa&#8221; de passar par\u00e2metros<\/a>. Precisaremos construir manualmente a string de consulta GET em &#8216;path&#8217;, como fiz acima: <code>'..\/getsomedata?product_id=14'<\/code>.<\/p>\n<p>Se voc\u00ea estiver interessado em como incorporar <code>wp.apiFetch<\/code>e personalizar endpoints em um bloco Gutenberg, escrevi um tutorial separado sobre isso:<\/p>\n<h3>Usando Javascript de baunilha<\/h3>\n<p>Como um exemplo final de m\u00e9todos Javascript para enviar solicita\u00e7\u00e3o para WP REST API, existe uma maneira baunilha pura, n\u00e3o WordPress, usando <code>fetch()<\/code>. Observe que eu uso a vari\u00e1vel global do WordPress para obter a URL raiz REST. Se voc\u00ea estiver adicionando este script fora do WordPress, provavelmente precisar\u00e1 codificar o URL completo.<\/p>\n<p>Como ainda quero acessar a vari\u00e1vel global para a URL raiz WP REST, adiciono <code>'wp-api-request'<\/code>depend\u00eancia \u00e0 minha fun\u00e7\u00e3o de enfileiramento Javascript, assim:<\/p>\n<pre><code>add_action( 'wp_enqueue_scripts', function() {\n    wp_enqueue_script(\n        'awp-javascript-wp-rest', \n        get_stylesheet_directory_uri(). '\/assets\/js\/javascript_wp_rest.js', \n        [ 'wp-api-request' ], \n        null, \n        true\n    );\n} );<\/code><\/pre>\n<p>E ent\u00e3o em nosso arquivo Javascript um exemplo mais b\u00e1sico seria:<\/p>\n<pre><code>function awpSendRequest() {\n    fetch( wpApiSettings.root + 'awhitepixel\/v1\/getsomedata?product_id=14', {\n        method: 'GET',\n    }) .then( data =&gt; data.json()) .then( data =&gt; {\n        console.log( data );\n    } );\n}\n\u00a0\nif (document.readyState != 'loading') {\n    awpSendRequest();\n} else {\n    document.addEventListener( 'DOMContentLoaded', awpSendRequest );\n}<\/code><\/pre>\n<p>Como mencionado acima (&#8220;Usando a biblioteca do WordPress&#8221;) <code>.fetch()<\/code>n\u00e3o suporta uma maneira agrad\u00e1vel e limpa de fornecer par\u00e2metros. Portanto, voc\u00ea precisar\u00e1 criar manualmente a string de consulta (&#8220;?product_id=14&#8221;) no URL.<\/p>\n<p>Tenha em mente que a solicita\u00e7\u00e3o de busca n\u00e3o retorna diretamente com os dados \u2013 ela retorna uma promessa. \u00c9 por isso que precisamos encadear &#8221; <code>.then()<\/code>&#8221; antes de podermos manipular os dados. Se isso soa estranho para voc\u00ea, recomendo procurar como trabalhar <code>fetch()<\/code>&#8211; h\u00e1 muitas explica\u00e7\u00f5es e exemplos no google que podem explicar melhor do que eu.<\/p>\n<p>Se voc\u00ea quiser verificar o c\u00f3digo de status da resposta REST para sua solicita\u00e7\u00e3o, fa\u00e7a assim;<\/p>\n<pre><code>fetch( wpApiSettings.root + 'awhitepixel\/v1\/getsomedata?product_id=14', {\n    method: 'GET',\n}) .then( data =&gt; {\n    if (data.status != 200) {\n        console.log( data.status + ' Error: ' + data.statusText );\n        return;\n    }\n    data.json().then( data =&gt; {\n        console.log( data );\n    } );\n} );<\/code><\/pre>\n<p>No exemplo acima ao registrar endpoints personalizados, mencionei como voc\u00ea pode retornar diferentes c\u00f3digos de status HTTP. O c\u00f3digo acima mostra um exemplo de como verificar o c\u00f3digo de status da resposta, que est\u00e1 dispon\u00edvel na propriedade do objeto retornado <code>.status<\/code>. No exemplo acima eu verifico se o c\u00f3digo de status \u00e9 diferente de 200 (Sucesso) na linha <code>#5<\/code>. Somente se o c\u00f3digo de status for 200 eu converto o retorno de dados da promessa em JSON (linha <code>#9<\/code>).<\/p>\n<h3>Usando PHP<\/h3>\n<p>\u00c9 menos comum, mas ainda poss\u00edvel, realizar requisi\u00e7\u00f5es REST internamente no WordPress usando PHP. Aqui est\u00e1 como.<\/p>\n<p>Para enviar uma solicita\u00e7\u00e3o WP REST API em PHP, criamos um <code>WP_REST_Request<\/code>objeto (exatamente como o que \u00e9 passado para nossa fun\u00e7\u00e3o de retorno de chamada anteriormente neste post). Nesta inst\u00e2ncia do objeto, definimos o m\u00e9todo (por exemplo, GET) e o caminho do endpoint. Opcionalmente, tamb\u00e9m podemos adicionar par\u00e2metros. Em seguida, usamos a fun\u00e7\u00e3o do WordPress <code>[rest_do_request](https:\/\/developer.wordpress.org\/reference\/functions\/rest_do_request\/)()<\/code>com esta inst\u00e2ncia de solicita\u00e7\u00e3o. Finalmente, obtemos a resposta com a <code>[response_to_data](https:\/\/developer.wordpress.org\/reference\/classes\/wp_rest_server\/response_to_data\/)()<\/code>fun\u00e7\u00e3o dispon\u00edvel na <code>WP_REST_Server'<\/code>classe s.<\/p>\n<pre><code>function awp_do_php_rest_request( $product_id) {\n    $request = new WP_REST_Request( 'GET', '\/awhitepixel\/v1\/getsomedata' );\n    $request-&gt;set_query_params( [\n        'product_id' =&gt; $product_id\n    ] );\n    $response = rest_do_request( $request );\n    return rest_get_server()-&gt;response_to_data( $response, false );\n}<\/code><\/pre>\n<p>A chamada de fun\u00e7\u00e3o <code>set_query_params()<\/code>(line <code>#3-5<\/code>) \u00e9 opcional e necess\u00e1ria apenas se voc\u00ea deseja passar par\u00e2metros. Seguindo o fio vermelho neste post, incluirei um exemplo de passagem do par\u00e2metro da fun\u00e7\u00e3o para o par\u00e2metro REST key <code>product_id<\/code>.<\/p>\n<p>A linha <code>#6<\/code>\u00e9 para onde enviamos a solicita\u00e7\u00e3o. E na linha <code>#7<\/code>retornamos os dados da resposta. Ent\u00e3o, se f\u00f4ssemos chamar essa fun\u00e7\u00e3o PHP, por exemplo <code>awp_do_php_rest_request( 14 )<\/code>, obter\u00edamos a resposta que definimos nesse endpoint (um array com uma string se voc\u00ea ainda usar o mesmo exemplo do in\u00edcio deste post).<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como criar endpoints REST personalizados do WordPress e diferentes m\u00e9todos para realizar solicita\u00e7\u00f5es a eles. Exemplos em PHP, jQuery e Javascript vanilla.<\/p>\n","protected":false},"author":1,"featured_media":151729,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,898,722,722,941,941,920,1110,920,846,846,867,867],"tags":[1170],"class_list":["post-233937","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-gutenberg-8","category-outro","category-n-a","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233937","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=233937"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233937\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/151729"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}