Suna un Server-side Metoda pe o Resursă într-un Mod Odihnitor

Păstrați în minte, am o înțelegere rudimentară de ODIHNĂ. Las's spun ca am acest URL:

http://api.animals.com/v1/dogs/1/

Și acum, vreau sa fac server de a face cainele sa latre. Doar serverul știe cum să facă acest lucru. Las's spun vreau să-l rula pe un loc de muncă CRON, care face cainele latra la fiecare 10 minute pentru restul eternității. Ce are asta de apel arata ca? Vreau pentru a face acest lucru:

Cerere URL:

ACTION http://api.animals.com/v1/dogs/1/

În corpul cererii:

{"action":"bark"}

Înainte de a te supăra pe mine pentru a face propria mea metoda HTTP, ajută-mă și dă-mi o idee mai bună despre cum ar trebui să invoce un server-side metodă într-un Odihnitor mod. :)

EDIT PENTRU CLARIFICARE

Unele mai multe clarificări în jurul a ce "coaja de" metodă de lucru. Aici sunt unele opțiuni care pot rezulta în mod diferit structurate apeluri API:

  1. coaja doar trimite un e-mail la câine.e-mail și înregistrări nimic.
  2. coaja trimite un e-mail la câine.e-mail și trepte de câine.barkCount de 1.
  3. coaja creează un nou "coaja de" înregistrare cu coaja.timestamp înregistrarea atunci când coaja s-a produs. Este, de asemenea, creșteri de câine.barkCount de 1.
  4. coaja se execută o comandă de sistem pentru a trage cea mai recentă versiune de câine codul de pe Github. Apoi trimite un mesaj text la câine.proprietar, spunându-le că câine nou cod este în producție.
Comentarii la întrebare (5)
Soluția

Ce vizează pentru un Odihnitor design?

Odihnitor principii aduce caracteristici care fac site-uri web ușor (o aleatoare utilizator uman la "naviga" i) la serviciile de web design API, astfel încât acestea sunt ușor pentru un programator să-l utilizați. RESTUL e't bun, deoarece's RESTUL, l's bun, deoarece's bune. Și este bine mai ales pentru că este simplu. Simplitatea HTTP simplu (fără SĂPUN plicuri și single-URI supraîncărcat "POST" servicii), ce unii ar putea numi "lipsa de caracteristici", este de fapt cea mai mare putere. Dreptul de pe bat, HTTP cere să ai adresabilitate și apatridie: la bază două decizii de proiectare care ține HTTP scalabil până la ziua de azi's mega-site-uri (și mega-servicii). Dar RESTUL nu este argint bulltet: Uneori, un RPC-stil ("Remote Procedure Call" - cum ar fi SĂPUN) poate fi adecvată, și, uneori, alte nevoi întâietate față de virtuțile de Web. Acest lucru este bine. Ceea ce nu ne't place este inutil complexitatea. De prea multe ori un programator sau o companie aduce în RPC-stil de Servicii pentru un loc de munca ca simplu vechi HTTP-ar putea descurca foarte bine. Efectul este că HTTP este redus la un protocol de transport pentru o enormă XML sarcină care explică de ce's "adevărat" întâmplă (nu URI sau metoda HTTP dau un indiciu despre asta). Rezultate serviciu este mult prea complex, imposibil de a depana, și a câștigat't funcționa decât dacă clienții tăi au exact setup ca dezvoltator destinat. Același mod un Java/C# cod poate fi nu orientat-obiect, folosind doar HTTP nu face un design Odihnitor. Unul poate fi prins în graba de thinking despre serviciile sale în ceea ce privește acțiunile de la distanță și metode care ar trebui să fie numit. Nu e de mirare că cea mai mare parte va ajunge într-un RPC-Stil de servicii (sau o perioadă de ODIHNĂ-RPC-hibrid). Primul pas este de a gândi diferit. Un Odihnitor design poate fi realizat în mai multe moduri, într-un fel (cel mai simplu, ar spune unii) este de a gândiți-vă de cererea dumneavoastră în termeni de resurse, nu acțiuni:

  • În loc de gândire în termeni de acțiuni ("a face o căutare pentru locuri de pe harta"),
  • Cred că în ceea ce privește rezultatele de acțiune ("lista de locuri de pe harta de potrivire un criteriu de căutare"). Am'll du-te pentru exemplele de mai jos. (Alte aspecte-cheie de ODIHNĂ este utilizarea de HATEOAS - am don't perie aici, dar eu vorbesc despre asta repede la un alt post.)

    Despre primul design

    Las's ia o privire un design propuse:

ACTION http://api.animals.com/v1/dogs/1/

În primul rând, noi nu ar trebui să ia în considerare crearea unui noi HTTP verb ("ACȚIUNE"). În general vorbind, acest lucru este nedorite pentru mai multe motive:

  • (1) Dat numai la service-URI, cum se va o "aleatorie" programator știu "ACȚIUNE" verb există?
  • (2) dacă programatorul știe că există, cum va sti sa semantica? Ceea ce înseamnă că verbul înseamnă?
  • (3) * ce proprietăți (de siguranță, idempotence) ar trebui să ne așteptăm că verbul a fi?
  • (4) dacă programatorul are o foarte simplu client care se ocupa numai standard HTTP verbe?
  • (5) ... Acum las's luați în considerare utilizarea "POST" (am'll discuta de ce mai jos, trebuie doar să ia cuvântul meu pentru asta acum):
POST /v1/dogs/1/ HTTP/1.1
Host: api.animals.com

{"action":"bark"}

Acest ar putea fi OK... dar doar:

  • {"de acțiune":"coaja de"} a fost un document; și
  • /v1/caini/1/ a fost o "procesor de documente" (fabrica-ca) URI. A "procesor de documente" este un URI care te'd doar "arunca lucrurile la" și "uita" despre ei - procesor le poate redirecționa la un nou create resurse după "aruncat". E. g. URI pentru postarea de mesaje la un mesaj broker de servicii, care, după postarea va redirecționa la un URI care indică starea de mesajul's de prelucrare. Eu nu't știu prea multe despre sistemul tau, dar am'd deja pariul ambele sunt't adevărate:
  • {"de acțiune":"coaja de"} nu este un document, chiar este metoda sunteți încercarea de a ninja-sneak* în serviciu; și
  • la /v1/caini/1/ URI reprezinta o "caine" de resurse (probabil câinele cu id==1) și nu un procesor de documente. Deci tot ce știu acum este că designul de mai sus nu este atât de Odihnitor, dar ce este mai exact? **Ce este atât de rău?!** Practic, este rău pentru că este complex URI cu semnificații complexe. Puteți't deduce nimic din ea. Cum ar fi un programator știu un câine au ocoaja` de acțiune care pot fi, în secret, infuzat cu un "POST" în ea?

    Proiectarea întrebarea ta's API apeluri

    Deci sa's trecem la subiect și să încercăm să proiectăm aceste latra Odihnitor de gândire în termeni de resurse. Permiteți-mi să citez Servicii Web Odihnitor carte:

    UN "POST" cerere este o încercare de a crea o nouă resursă de la un existent unul. Resursa existentă poate fi părintele unul nou într-o date-structura sens, modul în care rădăcina unui copac este părintele tuturor sa noduri frunze. Sau existente de resurse poate fi un special "fabrica" resurse al cărui singur scop este de a genera alte resurse. La reprezentare a trimis împreună cu un "POST" cerere descrie inițială starea de noi resurse. Ca cu PUI, un "POST" cererea nu are nevoie să include o reprezentare la toate. După descrierea de mai sus, putem vedea că coaja poate fi modelat ca o subresource de un "câine" (din o coaja este conținută într-un câine, care este, o coaja este "lătrat" de un câine). Din acest motiv avem deja:

  • Metoda "POST"
  • Resursa este /latra, subresource de câine: /v1/caini/1/latra, reprezentând o coaja "fabrica". Asta-URI este unic pentru fiecare câine (deoarece este sub /v1/caini/{id}). Acum fiecare caz din lista ta are un comportament specific.

    1. coaja doar trimite un e-mail la câine.e-mail și înregistrări nimic.

    În primul rând, este latra (trimiterea unui e-mail) un sincron sau asincron sarcina? În al doilea rând, nu coaja cerere solicita orice document (e-mail, poate) sau e gol?

    1.1 coaja trimite un e-mail la câine.e-mail și înregistrări nimic (ca o sarcină sincron)

    Acest caz este simplu. Un apel la latra fabrica de resurse dă o coaja (un e-mail trimis) imediat și răspunsul (dacă este OK sau nu) este dat imediat:

    POST /v1/caini/1/latra HTTP/1.1 
    Gazdă: api.animals.com 
    Autorizație: de Bază mAUhhuE08u724bh249a2xaP= 
    (entitate-corpul este gol - sau, dacă aveți nevoie de un **document**, pune-o aici) 
    200 OK 
    
    Cum se înregistrează (modificări) nimic, pentru 200 OK` este suficient. Acesta arată că totul a mers cum era de așteptat.
    ### 1.2 coaja trimite un e-mail la câine.e-mail și înregistrări nimic (ca o sarcină asincron) În acest caz, clientul trebuie să dispună de o modalitate de a urmări `coaja` de sarcini. De `coaja` de sarcină, atunci ar trebui să fie o resursă cu l's propriu-URI.:
    POST /v1/caini/1/latra HTTP/1.1 
    Gazdă: api.animals.com 
    Autorizație: de Bază mAUhhuE08u724bh249a2xaP= 
    {document organism, dacă este necesar; 
    NOTĂ: atunci când este posibil, răspunsul ar TREBUI să conțină o scurtă hypertext notă cu un hyperlink 
    la nou-creat de resurse (coaja) URI, la fel revenit în Locația antet 
    (observa, de asemenea, că, pentru 202 cod de stare, Locația antet sensul nu este 
    standardizate, astfel, importanța unui hipertext/hyperlink răspuns)} 
    202 Acceptat 
    Locație: http://api.animals.com/v1/dogs/1/barks/a65h44 
    
    În acest fel, fiecare `coaja` este urmărit. Clientul poate emite apoi o `GET` a `coaja` URI să-l cunosc's actuală de stat. Poate folosi chiar și un "DELETE" pentru a anula.
    ## 2. coaja trimite un e-mail la câine.e-mail și apoi trepte de câine.barkCount` de 1 Acesta poate fi mai complicată, dacă vrei să lași clientul să cunoască "câine" resource este schimbat:
    POST /v1/caini/1/latra HTTP/1.1 
    Gazdă: api.animals.com 
    Autorizație: de Bază mAUhhuE08u724bh249a2xaP= 
    {document organism, dacă este necesar; atunci când este posibil, conținând un hipertext/web link-ul cu adresa 
    în locul antet -- spune standardul} 
    303 a se Vedea Alte 
    Locație: http://api.animals.com/v1/dogs/1 
    
    În acest caz, "locație" antet's intenția este de a lasa pe client că el ar trebui să ia o privire la "câine". De [HTTP RFC despre `303`][4]: > Această metodă există în primul rând pentru a permite ieșirea dintr-un > ** "POST" -activat script** pentru a redirecționa utilizatorul de agent până la o anumită resursă. Dacă sarcina este asincron, o `coaja` subresource este nevoie ca de `1.2` situația și `303` ar trebui să fie returnate la un .../latra/Y` atunci când sarcina este finalizată.
    ## 3. coaja creează un nou "`coaja`" înregistrare cu coaja."timestamp" înregistrarea atunci când coaja s-a produs. Este, de asemenea, creșteri de câine.barkCount` de 1.
    POST /v1/caini/1/latra HTTP/1.1 
    Gazdă: api.animals.com 
    Autorizație: de Bază mAUhhuE08u724bh249a2xaP= 
    (document organism, dacă este necesar) 
    201 Creat 
    Locație: http://api.animals.com/v1/dogs/1/barks/a65h44 
    
    Aici, `coaja` este creat ca urmare a cererii, astfel încât statutul `201 Creat` este aplicat. Dacă creația este asincron, o `202 Acceptat` este necesar ([ca HTTP RFC spune][5]) în loc. Timestamp-a salvat este o parte de `coaja` de resurse și poate fi accesat cu un `AJUNG` la ea. Actualizat câine poate fi "documentate" în care `a LUA caini/X/latra/Y, la fel de bine.
    ## 4. coaja se execută o comandă de sistem pentru a trage cea mai recentă versiune de câine codul de pe Github. Apoi trimite un mesaj text la câine.proprietar`, spunându-le că câine nou cod este în producție. Textul acesta este complicat, dar este destul de mult este un simplu asincron sarcina:
    POST /v1/caini/1/latra HTTP/1.1 
    Gazdă: api.animals.com 
    Autorizație: de Bază mAUhhuE08u724bh249a2xaP= 
    (document organism, dacă este necesar) 
    202 Acceptat
    Locație: http://api.animals.com/v1/dogs/1/barks/a65h44 
    
    Clientul va emite `te să - `/v1/caini/1/latra/a65h44` să știi starea actuală (în cazul în care codul a fost tras, că e-mailul a fost trimis la proprietar și astfel). Ori de câte ori câinele modificări, o `303` e aplicabile.
    ## Ambalaj Cu Referire [Roy Fielding][6]: > singurul lucru Pe care RESTUL necesită metode este ca acestea să fie uniform > definite pentru toate resursele (de exemplu, așa că intermediarii nu trebuie să > cunosc tip de resursă, în scopul de a înțelege sensul de > cerere). În exemplele de mai sus, `POST` este uniform proiectat. Se va face dog "`coaja`". Nu este sigur (adica scoarta are efecte asupra resurselor), nici idempotent (fiecare cerere produce o nou `coaja`), care se potrivește "POST", verb bine. Un programator ar ști: un `POST` a `latra` dă-o `coaja`. Răspunsul coduri de stare (de asemenea, cu entitate-corp și cap atunci când este necesar) face treaba de a explica ce s-a schimbat și modul în care clientul poate și ar trebui să procedeze. Notă: sursele primare utilizate au fost: "[Servicii Web Odihnitor][3]" carte, [HTTP RFC][7] și [Roy Fielding's blog][8].

    --- **Edit:** Întrebarea și, astfel, răspunsul s-au schimbat destul de un pic de când au fost create în primul rând. La **întrebarea** întrebat despre design-URI, cum ar fi:
ACTION http://api.animals.com/v1/dogs/1/?action=bark

Mai jos este explicația de ce nu este o alegere buna: Ce spun clienții server CE SĂ FAC cu datele e metoda de informații.

  • Servicii web odihnitor transmite metodă de informații în metoda HTTP.
  • Tipic RPC-Stil și SĂPUN serviciile lor în corpul entității și antet HTTP. CARE face PARTE de date [vrea clientul server] pentru a opera pe e definire informații.
  • Servicii odihnitor utilizarea URI. SĂPUN/RPC-Stil de servicii folosi din nou corpul entității și antete HTTP. Ca un exemplu, să ia Google's URI http://www.google.com/search?q=DOG. Acolo, metoda de informații este de a "OBȚINE" și de definire a domeniului evaluării informațiilor este `/search?q=CÂINE. Povestea pe scurt:
  • În Odihnitor arhitecturi, metoda de informații intră în metoda HTTP.
  • În Resurse-Arhitecturi Orientate pe servicii, de definire a domeniului evaluării informațiilor merge într URI. Și regula de degetul mare:

    Dacă metoda HTTP nu se potrivește metoda de informații, serviciul nu este Odihnitor. Dacă definire informații nu este în URI, serviciul nu este orientat spre resurse. Puteți pune "coaja de" "de acțiune" în URL-ul (sau în corpul entității) și de a folosi "POST". Nici o problemă, funcționează, și poate fi cel mai simplu mod de a face asta, dar nu't Odihnitor. Pentru a păstra dvs. de servicii cu adevărat Odihnitor, va trebui să ia un pas înapoi și cred despre ceea ce vrei cu adevărat să faci aici (ce efecte va avea asupra resurselor). Pot't vorbi despre nevoile dvs. de afaceri specifice, dar lasă-mă să vă dau un exemplu: Considerăm un Odihnitor serviciu de comanda în cazul în care comenzile sunt la uri-Uri ca example.com/order/123. Acum spunem că doriți să anulați o comandă, cum vom face asta? Unul poate fi tentat să cred că este o "anularea" "de acțiune" și design ca POST example.com/order/123?do=cancel. Că nu este Odihnitor, așa cum am vorbit mai sus. În schimb, am putea "PUNE" o nouă reprezentare a "comenzii" cu o anulat element trimis la "true":

PUT /order/123 HTTP/1.1
Content-Type: application/xml


    ...
    true
    ...

Și că's a. Dacă comanda poate't fi anulat, un anumit cod de stare pot fi returnate. (O subresource de design, cum ar fi POST /comanda/123/anulat cu corpul entității "adevărat", poate, pentru simplitate, fi, de asemenea, disponibile.)</sup> În scenariu specific, s-ar putea încerca ceva similar. Așa, în timp ce un câine latră, de exemplu, oAJUNGla/v1/caini/1/ar putea include informații <sup>(de exemplu,adevărat`). Sau... daca's prea complicat, dezleagă-ți Odihnitor cerință și stick cu "POST".

Update:

Eu nu't vreau pentru a face răspunsul prea mare, dar este nevoie de un timp pentru a obține atarna de a expune un algoritm (o acțiune) ca un set de resurse. În loc de a gândi în termeni de acțiuni ("a face o căutare pentru locuri de pe harta"), trebuie să gândim în termeni de rezultate de acțiune ("lista de locuri de pe harta o căutare de potrivire criterii"). Ați putea găsi te întorci la acest pas, dacă veți găsi că design-ul nu - 't se potrivesc HTTP's interfață uniformă. Interogare de variabile sunt definire informații, dar *nu * denotă noi resurse (/post?lang=ro este în mod clar acelasi resurse ca /post?lang=jp, doar o reprezentare diferită). Mai degrabă, ele sunt folosite pentru a transmite clientul de stat (ca ?page=10, astfel încât statul nu este ținut în server; ?lang=ro este, de asemenea, un exemplu aici) sau parametri de intrare* la algoritmică resurse* (/search?q=câini, /câini?cod=1). Din nou, nu resurse distincte.

HTTP verbe' (metode) proprietăți:

Un alt punct clar că arată `?acțiune=ceva în URI nu este Odihnitor, sunt proprietățile de verbe HTTP:

  • "A LUA" și " ȘEF " sunt sigur (și idempotent);
  • "PUNE" și "DELETE" sunt idempotent numai;
  • "POST" nu este nici. Siguranță: O "a LUA" sau " ȘEF " cerere este o cerere de a citiți unele date, nu o cerere pentru a schimba orice server de stat. Clientul poate face o "a LUA" sau " ȘEF " cerere de 10 ori și-l's la fel ca făcându-l o dată, sau nu face deloc. Idempotence: O operație idempotentă într-una care are același efect indiferent dacă se aplică o dată sau de mai multe ori (în matematică, înmulțirea cu zero este idempotent). Dacă "ȘTERGE" o resursă dată, ștergerea din nou va avea același efect (resursa este "PLECAT" deja). "POST" nu este nici sigur, nici idempotent. Face două identice "POST" cererile de a o 'fabrica' resurse va duce, probabil, în două subordonat resurse care conțin aceeași informații. Cu supraîncărcat (metoda URI sau entitate-corp) "POST", toate pariurile sunt oprite. Ambele aceste proprietăți sunt importante pentru succesul de protocolul HTTP (peste rețele nesigure!): de câte ori ați actualizat ("a LUA") pagina fără a aștepta până când este complet încărcată? Crearea unui acțiune și plasându-l în URL-ul în mod clar sparge metode HTTP' contract. Din nou, tehnologia permite, o poti face, dar asta nu este Odihnitor design.
Comentarii (20)

Am răspuns mai devreme](https://stackoverflow.com/a/16997574/972499), dar acest răspuns contrazice vechiul meu răspuns și urmează o altă strategie pentru a veni la o soluție. Ea arată cum cererea HTTP este construit din conceptele care definesc ODIHNĂ și HTTP. Se utilizează, de asemenea, "PATCH" în loc de "POST" sau "PUNE". Se trece prin RESTUL constrângeri, atunci componentele de HTTP, atunci o soluție posibilă.

ODIHNA #

RESTUL este un set de constrângeri destinat să fie aplicat un sistem hipermedia distribuite în scopul de a face scalabile. Chiar și să facă sens de ea în contextul controlul la distanță o acțiune, trebuie să te gândești la distanță controlează o acțiune, ca parte a unui sistem hipermedia distribuite-o parte dintr-un sistem pentru a descoperi, vizualizarea si modificarea interconectate informații. Dacă asta's mai multe probleme decât a's valoare, atunci's, probabil, nu este bine să încercați să-l facă Odihnitor. Daca vrei doar un "panou de control" tip GUI pe client, care poate declanșa acțiuni de pe server prin portul 80, atunci veți dori, probabil, o simplă RPC interface ca JSON-RPC prin HTTP cereri/răspunsuri sau un WebSocket. Dar RESTUL este un mod fascinant de a gândi și de exemplul în cauză se întâmplă să fie ușor pentru model cu un Odihnitor interfață, astfel încât să's ia pe provocare pentru distracție și pentru educație. RESTUL este definit de patru interfață constrângeri:

identificarea resurselor; manipulare a resurselor prin reprezentări; auto-descriptive mesaje; și, hypermedia ca motor al cererii de stat. Vă întrebați cum puteți defini o interfață, săli de aceste constrângeri, prin care un calculator spune un alt computer pentru a face un latrat de câine. Mai exact, vrei interfața pentru a fi HTTP, și tu nu't doriți să aruncați caracteristici care fac HTTP Odihnitor atunci când sunt utilizate conform destinației. Las's începe cu prima constrângere: identificarea resurselor necesare. Orice informație care poate fi numit poate fi o resursă: un document sau o imagine, o temporală de servicii (de exemplu, "astazi's vreme în Los Angeles"), o colecție de alte resurse, un non-obiect virtual (de exemplu, o persoană), și așa mai departe. Așa că un câine este o resursă. Aceasta trebuie să fie identificate. Mai precis, o resursă R este un material diferite funcția de membru MR(t), care, pentru moment t hărți pentru un set de entități, sau valori, care sunt echivalente. Valorile din set pot fi resource representations și/sau resource identifiers. Ai model un câine de a lua un set de identificatori și reprezentări și spunând acestea sunt toate asociate cu fiecare alte la un moment dat. Pentru moment, să's a folosi identificatorul "cainele #1". Asta ne aduce la al doilea și al treilea constrângeri: reprezentarea resurselor și auto-descriere. RESTUL componentelor efectua acțiuni pe o resursă folosind o reprezentare a capta curente sau planificate de stat al resurselor și transferul de reprezentare între componente. O reprezentare este o secvență de octeți, plus reprezentarea metadatelor pentru a descrie acele bytes. Următoarele este o secvență de octeți capturarea destinat stat de câine, și anume, reprezentarea ne-am dori să fie asociat cu identificatorul "cainele #1" (rețineți că aceasta reprezintă doar o parte a statului, deoarece nu are în vedere câine's nume, de sănătate, sau chiar trecut latra): a fost latra la fiecare 10 minute din timp, acest stat modificare a fost efectuată, și va continua pe termen nelimitat. Acesta ar trebui să fie atașat la metadate care îl descrie. Aceste metadate ar putea fi utile: este o engleză declarație. Acesta descrie o parte a scopului statului. Dacă este primit de mai multe ori, doar pentru a permite în primul rând să aibă un efect. În cele din urmă, să's se uite la cea de-a patra constrângere: HATEOAS. RESTUL ... vedere o aplicație ca o structură coerentă de informații și de control alternative prin care un utilizator poate efectua o sarcina dorită. De exemplu, căutarea unui cuvânt într-un dicționar este o aplicație, cum este turul prin muzeu virtual, sau revizuirea unui set de note de clasă pentru a studia pentru un examen. ... Urmatorul control de stat de o aplicație constă în reprezentarea în primul rând de resurse solicitate, obținând astfel că prima reprezentare este o prioritate. ... Modelul de cerere este, prin urmare, un motor care se mișcă de la o stare la alta prin examinarea și alegerea dintre alternative tranziții de stat în actualul set de reprezentări. Într-un Odihnitor interfață, clientul primește o resursă reprezentare în scopul de a da seama cum ar trebui să primească sau să trimită un reprezentant. Trebuie să existe o reprezentare undeva în aplicare, din care clientul poate da seama cum de a primi sau a trimite toate reprezentările ar trebui să fie capabil de a primi sau trimite, chiar dacă urmează un lanț de reprezentări pentru a ajunge la aceste informații. Acest lucru pare destul de simplu: Clientul solicită o reprezentare a unei resurse identificate ca pagină de pornire; ca răspuns, ea devine o reprezentare care conține un identificator de fiecare câine pe care clientul le-ar putea dori. Clientul extrage un identificator de aceasta și solicită servicii cum pot interacționa cu cele identificate de câine, și la serviciu, spune clientul poate trimite o engleză declarație care descrie o parte din cele destinate statului de câine. Apoi clientul trimite o astfel de declarație și primește un mesaj de succes sau un mesaj de eroare.

HTTP #

HTTP implementează RESTUL constrângeri, după cum urmează: identificarea resurselor necesare: URI resurse de reprezentare: entitate-corp auto-descriere: metodă sau cod de stare, antete, și, eventual, părți din corpul entității (de exemplu, URI de o schemă XML) HATEOAS: link-uri Te'am decis pe http://api.animals.com/v1/dogs/1` ca-URI. Las's presupunem că clientul a luat asta de la o pagină de pe site-ul. Las's utilizați această entitate-corp (valoarea de "next" este un marcaj de timp, o valoare de " 0 " înseamnă 'atunci când această cerere este primit'):

{"barks": {"next": 0, "frequency": 10}}

Acum avem nevoie de o metodă. PATCH se potrivește "parte a destinat stat" descriere ne-am decis pe:

PATCH-uri metodă solicită un set de modificări descrise în cererea entității fi aplicate la resursa identificată de Request-URI. Și unele antete: Pentru a indica limba de corpul entității: Content-Type: application/json Pentru a vă asigura că se întâmplă doar o dată: Dacă-Nemodificat-Deoarece: <data/ora acesta a fost primul trimis> Și avem o cerere:

PATCH /v1/dogs/1/ HTTP/1.1
Host: api.animals.com
Content-Type: application/json
If-Unmodified-Since: 
[other headers]

{"barks": {"next": 0, "frequency": 10}}

Pe succes, clientul ar trebui să primească o 204 cod de stare în răspuns, sau un 205 dacă reprezentarea /v1/caini/1/ a schimbat pentru a reflecta noua latra program. În caz de eșec, ar trebui să primească o 403 și un mesaj de ajutor și de ce. Nu este esențial să se ODIHNEASCĂ pentru serviciul de a reflecta coaja de program într-o reprezentare, ca răspuns la IA /v1/caini/1/, dar ar face mai mult sens dacă o JSON reprezentare a inclus:

"barks": {
    "previous": [x_1, x_2, ..., x_n],
    "next": x_n,
    "frequency": 10
}

Trata cron de locuri de muncă ca o punere în aplicare detaliu care serverul ascunde de interfață. Ca's frumusețea unui generic de interfață. Clientul nu't trebuie să știe ce server are în spatele scenei, tot ce-i pasă este că serviciul înțelege și răspunde la stat solicitat modificări.

Comentarii (0)

Cei mai mulți oameni folosesc POST pentru acest scop. Este adecvat pentru efectuarea de "orice nesigure sau nonidempotent funcționare atunci când nici o altă metodă HTTP pare adecvat".

Api-uri, cum ar fi [XMLRPC][1] utilizare MESAJ pentru a declanșa acțiuni care pot rula cod arbitrar. "de acțiune" este inclus în POST date:


POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>

   examples.getStateName
   <params>
      <param>
         41
Comentarii (6)

"POST" este HTTP metoda conceput pentru

Asigurarea unui bloc de date de la un date-proces de manipulare

Server-side metode de manipulare non-CRUD-mapate acțiuni este ceea ce Roy Fielding destinat cu RESTUL, deci're de bine acolo, și că's de ce "POST" a fost făcut pentru a fi non-idempotent. "POST" se va ocupa de cele mai postarea de date a server-side metode de a procesa informațiile.

Asta a spus, în câine-a lătrat scenariu, dacă vrei un server-side coaja să fie efectuate la fiecare 10 minute, dar pentru un motiv oarecare nevoie de declanșare să provină de la un client, "PUNE" ar servi scopului mai bine, din cauza idempotence. Ei bine, strict de acest scenariu nu's, aparent fără riscul de mai multe cereri POST provocând cainele sa miaune în loc, dar oricum asta's scopul celor două metode similare. Răspunsul meu la o similară ATÂT de întrebare poate fi util pentru tine.

Comentarii (1)

Revizii mai devreme de unele răspunsuri au sugerat utilizați RPC. Nu aveți nevoie să se uite la RPC ca este perfect posibil să faci ce vrei în timp ce aderarea la RESTUL constrângeri.

În primul rând, don't pune parametri de acțiune în URL-ul. URL-ul definește ce se aplică acțiunea sa, și parametrii de interogare sunt parte a URL-ului. Ar trebui să fie gândit în întregime ca un substantiv. http://api.animals.com/v1/dogs/1/?action=bark este o altă resursă — un alt substantiv — a http://api.animals.com/v1/dogs/1/. [n.b. Asker-a eliminat ?acțiune=scoarta URI de întrebare.] De exemplu, compara http://api.animals.com/v1/dogs/?id=1 " la " http://api.animals.com/v1/dogs/?id=2. Resurse diferite, se disting numai prin șir de interogare. Deci acțiunea de cerere, cu excepția cazului în care aceasta corespunde direct la un bodyless existente, metodă de tip (TRACE, OPȚIUNI, CAP, pentru a PRIMI, ȘTERGE, etc) trebuie să fie definite în corpul cererii.

Apoi, decide dacă acțiunea este "idempotent", în sensul că aceasta poate fi repetată fără efecte adverse (a se vedea paragraful următor pentru mai multe explanaton). De exemplu, stabilind o valoare de adevărat poate fi repetată în cazul în care clientul nu este sigur că efectul dorit s-a întâmplat. Se trimite cererea din nou, iar valoarea rămâne adevărat. Adăugarea de 1 la un număr nu este idempotent. Dacă clientul trimite Add1 comanda, e't de sigur că ea a lucrat, și trimite-l din nou, nu-server adăuga una sau două? Odată ce ați stabilit că, ai're într-o poziție mai bună pentru a alege între "PUNE" și "POST" pentru metoda ta.

Idempotent înseamnă o cerere poate fi repetată fără a schimba rezultatul.* Aceste efecte nu includ logare și alte astfel de server admin activitate. Folosind prima și a doua exemple, trimite două e-mailuri de la aceeași persoană se duce într-un alt stat decât expedierea unui e-mail (destinatar a doua în inbox-ul lor, care le-ar putea considera a fi spam-ul), deci mi-ar folosi cu siguranta POST pentru asta. Dacă barkCount în exemplul 2 este destinat să fie văzut de un utilizator de API sau afecteaza ceva care este client-vizibile, atunci este, de asemenea, ceva care ar face cerere non-idempotent. Dacă este doar pentru a fi vizualizate de către tine, atunci nu conteaza ca server de logare și ar trebui să fie ignorate atunci când de stabilire a idempotentcy.

În ultimul rând, a determina dacă acțiunea pe care doriți să efectuați poate fi de așteptat pentru a reuși imediat sau nu. BarkDog este o repede completarea de acțiune. RunMarathon nu este. Dacă acțiunea este lent, ia în considerare returnarea 202 Acceptat, cu o adresă URL în răspunsul organismului pentru un utilizator la sondaj pentru a vedea dacă acțiunea este completă. Alternativ, utilizatorii au POST la o listă de URL-ul ca /maratoanele-in-progress/ și atunci când acțiunea este făcut, le redirecționa la cele în curs ID-ul URL-ul de la /maratoanele-complet/ URL. Pentru cazuri specifice #1 și #2, mi-ar fi de gazdă al serverului-o coadă, iar clientul post loturi de adrese de la ea. Acțiunea nu ar fi SendEmails, dar ceva de genul AddToDispatchQueue. Serverul poate atunci sondaj coada de așteptare pentru a vedea dacă există orice adrese de e-mail în așteptare, și trimite e-mailuri în cazul în care constată orice. Atunci actualizări la coadă pentru a indica faptul că în curs de acțiune a fost realizată. Ar fi o altă URI arată clientului starea curentă a cozii. Pentru a evita dubla-trimiterea de e-mailuri, serverul ar putea, de asemenea, ține un jurnal de cine l-a trimis acest e-mail, și de a verifica fiecare adresa asta pentru a se asigura că nu trimite niciodată două la aceeași adresă, chiar dacă POSTAȚI aceeași listă de două ori la coadă.

Atunci când alegeți un URI pentru nimic, încercați să cred că de ea ca un rezultat, nu o acțiune. De exemplu, google.com/search?q=dogs arată rezultate de căutare pentru cuvântul "cainii". Nu neapărat a efectua căutarea.

Cazuri #3 și #4 din lista ta sunt, de asemenea, nu idempotent acțiuni. Ai sugerează că diferite sugerat efecte ar putea afecta API design. În toate cele patru cazuri mi-ar folosi același API, ca toate cele patru schimba "lume stat".

Comentarii (2)

Dacă presupunem Latratul este un interior / dependente / sub resurselor de care consumatorul poate acționa, atunci am putea spune:

POST http://api.animals.com/v1/dogs/1/bark

câinele numărul 1 latra

GET http://api.animals.com/v1/dogs/1/bark

returnează ultima coaja timestamp

DELETE http://api.animals.com/v1/dogs/1/bark

nu't se aplică! deci, ignora-l.

Comentarii (2)

A se vedea meu nou răspuns -- l contrazice asta și explică de ODIHNĂ și HTTP mult mai clar și precis.

Aici's a *recomandare *** care se întâmplă să fie Odihnitor, dar cu siguranță nu este singura opțiune. A început să latre atunci când serviciul primește cererea:

POST /v1/dogs/1/bark-schedule HTTP/1.1
...
{"token": 12345, "next": 0, "frequency": 10}

"simbolică" este un număr arbitrar care previne redundante latra nu contează cât de multe ori această cerere este trimis.

"următorul" indică de coaja; - o valoare de " 0 " înseamnă 'ACUM'.

Ori de câte ori te `IA /v1/caini/1/coaja-program, ar trebui să obțineți ceva de genul asta, unde t este ultima coaja si u este t + 10 minute:

{"ultima": t, "de lângă": u}

Am foarte recomandăm să utilizați aceeași adresă URL pentru a solicita o coaja pe care le utilizați pentru a afla despre dog's actuală latra de stat. L's nu este esențial să se ODIHNEASCĂ, dar ea pune accentul pe actul de modificare a programului.

Starea corespunzătoare codului este, probabil, 205. Am'm a imagina un client care se uita la programul actual, `POST la același URL să-l schimbe, și este instruit de serviciu să dea programa o a doua privire pentru a dovedi că a fost schimbat.

Explicația

ODIHNA

Uita HTTP pentru un moment. L's esențială pentru a înțelege că un resurse este o funcție care are nevoie de timp ca intrare și returnează un set care conține identifiers și representations. Las's simplifica care să: o resursă este un set R de identificare și reprezentare; R poate schimba -- membrii pot fi adăugate, șterse sau modificate. (Deși-l's rău, instabil design de a elimina sau modifica de identificare.) Spunem un identificator, care este un element de R identifică R, și că o reprezentare, care este un element de R reprezintă R.

Las's spun R este un câine. Se întâmplă să identifice R ca /v1/caini/1. (Sensul /v1/caini/1 este un membru al R.) Ca's doar una dintre mai multe moduri de a identifica R. Ai putea identifica, de asemenea, R ca `/v1/caini/1/x-raze " sau " /v1/lui rufus.

Cum să reprezinți R? Poate cu o fotografie. Poate cu un set de radiografii. Sau, poate, cu indicarea datei și orei când R ultima lătrat. Dar amintiți-vă că acestea sunt toate reprezentări ale the același resource. `/v1/caini/1/x-rays este un identificator de aceeași resursă este reprezentată de un răspuns la întrebarea "atunci când v-R ultima coaja?"

HTTP

Mai multe reprezentări a unei resurse nu't foarte util dacă puteți't se referă la o doriți. Ca's de ce HTTP este util: vă permite să se conecteze de identificare a reprezentărilor. Asta este, acesta este un fel de serviciu pentru a primi o adresă URL și de a decide care de reprezentare pentru a servi la client.

Cel puțin, asta's ce "OBȚINE" are. "PUNE" este de fapt inversul "a LUA": te a PUS o reprezentare r la URL-ul, dacă doriți pentru viitor "OBȚINE" cereri la acel URL pentru a reveni r, cu unele traduceri posibile ca JSON HTML.

"POST" este un looser mod de a modifica o reprezentare. Cred că de acolo fiind logica de afișare și modificare logica, care sunt omologii reciproc-atât corespunzătoare la același URL. O cerere POST este o cerere pentru modificarea logica pentru a procesa informații și de a modifica orice reprezentare (nu doar reprezentarea situat de aceeași URL-ul), ca serviciu de cuviință. Acorde o atenție la cel de-al treilea paragraf, după 9.6 PUNE: - ai're nu înlocuirea lucru la URL-ul cu un conținut nou; te're a cere ceva de la URL-ul pentru a procesa anumite informații și inteligent răspunde în formă de informativ reprezentări.

În cazul nostru, ne cere modificarea logica la /v1/caini/1/coaja-program (care este omologul a afișa logica ne spune că atunci când ultima lătrat și când va următorul coaja) de a procesa informații și de a modifica unele reprezentări în mod corespunzător. Ca răspuns la viitor `te, display logica corespunzătoare la același URL ne va spune că câinele este acum latra ca ne-am dori.

Cred că de locuri de muncă cron ca o punere în aplicare detaliu. HTTP oferte în vizualizarea și modificarea reprezentărilor. De acum, serviciul va spune clientul, atunci când câinele ultima lătrat și atunci când acesta va latra viitoare. De la serviciu's perspectiva, care este cinstit pentru acele momente corespund cu trecutul și planificat de locuri de muncă cron.

Comentarii (0)

RESTUL este o resursă orientate standard, nu este condus de acțiune ca un RPC ar fi.

Dacă doriți ca serverul să coaja, ar trebui să se uite în diferite idei de genul JSON-RPC, sau în websockets de comunicare.

Fiecare încearcă să-l țină Odihnitor va eșua în opinia mea: puteți emite un "POST" cu "acțiune" parametru, nu crearea de noi resurse, dar ca poate avea efecte secundare, sunt mai sigure.

Comentarii (2)