De ce nu funcționează endpoint-ul meu personalizat pentru API?
Am încercat să includ acest cod în fișierele php ale plugin-ului meu, precum și în functions.php
.
(În final aș dori să fie în fișierul php al plugin-ului dar nu sunt încă sigur dacă e posibil, asta ar fi probabil subiectul unei alte întrebări.)
Este o metodă foarte simplă pentru moment, încerc doar să obțin un răspuns cu niște conținut.
În ambele cazuri, primesc un răspuns 404.
add_action( 'rest_api_init', function () {
register_rest_route( plugin_dir_url(__DIR__).'my-project/api/v1/form', '/action', array(
'methods' => 'GET, POST',
'callback' => 'api_method',
) );
});
function api_method($data) {
var_dump($data);
return 'Sfârșitul metodei API.';
}
Și am încercat să accesez URL-urile (în browser sau cu AJAX)
- http://my-domain.local/wp-content/plugins/my-project/api/v1/form
- http://my-domain.local/wp-content/plugins/my-project/api/v1/form/
- http://my-domain.local/wp-content/plugins/my-project/api/v1/form/get
- http://my-domain.local/wp-content/plugins/my-project/api/v1/form/get/
Cred că omit ceva.

Iată problema ta:
register_rest_route( plugin_dir_url(__DIR__).'my-project/api/v1/form', '/action', array(
Mai exact ideea că acest lucru este posibil:
http://my-domain.local/wp-content/plugins/my-project/api/v1/form
Acest lucru este extrem de neobișnuit și contravine documentației, ghidurilor și tutorialelor.
Endpoint-urile REST API trăiesc în cadrul REST API, care se află la URL-ul returnat de rest_url()
. Ele se află la yoursite.com/wp-json
. Un endpoint nu este un URL complet sau un API independent deconectat de API-ul principal.
În schimb, trebuie să-ți definești numele endpoint-urilor în termeni de namespace-uri și endpoint-uri și să vizitezi URL-ul corect așa cum este descris în mecanismele de descoperire ale REST API.
Dacă folosim acest lucru:
register_rest_route( plugin_dir_url(__DIR__).'my-project/api/v1/form', '/action', array(
Atunci ne-am aștepta la acest lucru:
example.com/wp-json/wp-content/plugins/my-project/api/v1/form/action
Acest URL este destul de lung și are o serie de probleme:
- Primul parametru este un namespace, nu un URL
- nu este posibil să separi corect versiunea v1 a API-ului de v2 datorită modului în care componenta
/form
a fost pusă în primul parametru, nu în al doilea. Primul parametru este un namespace, al doilea este o rută /action
este/action
, nu este înlocuit cuGET
sauPOST
Există și probleme cu funcția de callback:
function api_method($data) {
var_dump($data);
Un endpoint trebuie să returneze datele, nu le poate afișa direct așa cum ar face var_dump
, altfel datele returnate nu sunt un JSON valid.
În cele din urmă, parametrul methods este incorect:
'methods' => 'GET, POST',
methods
nu acceptă o listă separată prin virgulă, nici documentația nu sugerează acest lucru. În schimb, folosește valorile predefinite oferite de REST API, cum ar fi WP_REST_Server::READABLE
sau WP_REST_Server::ALLMETHODS
, acestea sunt menționate în ghid și în documentația oficială pentru register_rest_route
.
O rută mai bună de înregistrat ar fi:
register_rest_route( 'my-project/form/v1', '/action', array(
Dându-ne:
example.com/wp-json/my-project/form/v1/action
Observă cum am eliminat URL-ul pluginului și fragmentul redundant /api
(este deja evident că este un API)

Mulțumesc pentru explicația detaliată. Totuși, am marcat deja un răspuns care a venit mai repede ca soluție.

Poți să-ți schimbi părerea despre care răspuns este cel mai bun, dar în orice caz gândește-te la acest site ca la o wiki - pot exista mai multe răspunsuri bune

Un motiv pentru care nu doresc să schimb răspunsul este că am testat concret și am aplicat soluția pe care am selectat-o. Răspunsul tău a adus mai multe detalii și a corectat unele concepții greșite ale mele, dar nu le-am testat și verificat pe toate literalmente.
De asemenea, cred că pe majoritatea site-urilor StackExchange, primele răspunsuri bune sunt selectate, iar următoarele primesc voturi. Deși asta mă face să mă zgâriesc puțin la cap, nu văd niciun motiv să retrag recompensa soluției de la persoana care a rezolvat-o primul.

Poți începe doar cu GET
. Ruta ta arată, de asemenea, ciudat. Încearcă doar:
register_rest_route('my-project/v1', '/action/', [
'methods' => WP_REST_Server::READABLE,
'callback' => 'api_method',
]);
Și callback-ul tău nu returnează un răspuns valid. Lasă callback-ul tău să arate mai mult așa:
$data = [ 'foo' => 'bar' ];
$response = new WP_REST_Response($data, 200);
// Setează antete.
$response->set_headers([ 'Cache-Control' => 'must-revalidate, no-cache, no-store, private' ]);
return $response;
În final, trebuie să combini wp-json
, namespace-ul my-project/v1
și ruta ta action
pentru URL-ul pe care acum îl poți verifica pentru a vedea ce primești:
https://my-domain.local/wp-json/my-project/v1/action

Tocmai am urmat sugestia ta, am încercat http://my-domain.local/my-project/v1/ , http://my-domain.local/my-project/v1/get/ (cu și fără slash la final), dar tot primesc răspuns 404. Momentan, codul este în functions.php.

@TTT – Trebuie să fie https://my-domain.local/wp-json/my-project/v1/action așa cum ai specificat /action/
să fie ruta ta.

Mulțumesc, a funcționat. Deoarece răspunsul este în comentariu, nu sunt sigur dacă ar trebui să marchezi răspunsul ca soluție imediat.
De asemenea, pot face ca acesta să returneze altceva decât JSON, nu? (Adică nu ca XML, ci cod HTML procesat de php.) ... Atunci URL-ul ar conține tot "wp-json". Ciudat ... sau există alt tip de API?

@TTT poți stoca HTML în JSON ca un șir de caractere și apoi să decodezi JSON în browser

Tocmai am găsit și testat această metodă care pare mai curată decât includerea HTML în JSON: https://gist.github.com/petenelson/6dc1a405a6e7627b4834

În cazul meu, trebuie doar să adaug wp-json în URL-ul expeditorului webhook, ceea ce va rezulta în
https://my-domain.local/wp-json/my-plugin/v1/action
iar în fișierul meu functions.php aceste linii de cod funcționează
add_action('rest_api_init', 'register_webhook_endpoint');
function register_webhook_endpoint() {
register_rest_route('my-plugin/v1', '/action', array(
'methods' => 'POST',
'callback' => 'handle_webhook_request',
));
}
function handle_webhook_request(WP_REST_Request $request) {
// Procesează cererea webhook
$data = $request->get_body(); // Obține corpul cererii
// Efectuează acțiuni bazate pe datele primite prin webhook
// Returnează un răspuns dacă este necesar
return new WP_REST_Response('Webhook primit.', 200);
}
