De ce nu funcționează endpoint-ul meu personalizat pentru API?

10 apr. 2019, 17:30:12
Vizualizări: 18.3K
Voturi: 6

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)

Cred că omit ceva.

3
Comentarii

Endpointurile REST API se găsesc la /wp-json, includerea plugin_dir_url în înregistrarea endpointului este extrem de neobișnuită, aș recomanda cu tărie să evitați URL-urile endpointurilor REST în folderul pluginurilor (în principal pentru că API-ul nu funcționează așa, nu puteți avea astfel de URL-uri)

Tom J Nowell Tom J Nowell
10 apr. 2019 18:07:53

@TomJNowell – Poți vedea de ce această întrebare a primit atât de multe vizualizări într-un timp atât de scurt? Ar trebui să întreb asta pe Meta?

norman.lol norman.lol
11 apr. 2019 00:40:59

să întrebi pe meta este o idee bună, nu sunt sigur cum putem vedea vizualizările. Poate întrebarea ta a fost bine scrisă și populară? :)

Tom J Nowell Tom J Nowell
11 apr. 2019 12:20:13
Toate răspunsurile la întrebare 3
3

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 cu GET sau POST

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)

10 apr. 2019 18:19:18
Comentarii

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

TTT TTT
10 apr. 2019 18:25:42

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

Tom J Nowell Tom J Nowell
10 apr. 2019 20:21:00

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.

TTT TTT
10 apr. 2019 20:42:32
6

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
10 apr. 2019 17:36:51
Comentarii

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 TTT
10 apr. 2019 18:02:18

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

norman.lol norman.lol
10 apr. 2019 18:12:34

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 TTT
10 apr. 2019 18:17:23

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

Tom J Nowell Tom J Nowell
10 apr. 2019 18:20:00

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

TTT TTT
10 apr. 2019 19:01:03

@TTT – Super! Mulțumesc pentru share. Am salvat linkul.

norman.lol norman.lol
10 apr. 2019 19:27:59
Arată celelalte 1 comentarii
0

Î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);
}
5 iun. 2023 20:58:52