RESTful API-n egy GET hívásnak lehet-e body-ja?

Címkék

Lehet.
9% (9 szavazat)
Ha nagyon muszáj (pl. query paramba nem fér), akkor lehet.
18% (18 szavazat)
Nem lehet.
49% (50 szavazat)
Nem érdekel, RPC-ként használom.
25% (25 szavazat)
Összes szavazat: 102

Hozzászólások

Egy hatalmas gráf részgráfját szeretnénk visszakapni, egy (már a kliens oldalon fába szervezett) lekérdezőnyelvvel. Nyilván query paramba tenni igen csúnya megoldás lenne, ezért felmerült több ötlet is, mindegyik sántít:

0) De nem érdekel, hogy csúnya, query paramba menjen!
A query paramnak van maximális hossza, amit semmiképp sem akarunk túllépni.
1) POST-oljunk oszt jóvan.
Nem túl REST szerű... Nem akarunk erőforrást létrehozni a szerveren, lekérdezni akarunk.
2) POST-olunk ÉS GET-elünk
POST-tal feltoljuk a queryt (létrehozunk egy query resource-ot), majd GET-tel lekérjük azt a részgráfot, amit a queryparamban küldött queryId által hivatkozott query kiköp. Ez tűnik a leg-REST-ebbnek, na de hát két http kérés...?
3) GET-elünk payloaddal
Erről szól a kérdés. JSON-ban, a body részeként feltoljuk a queryt, megkapjuk a részgráfot.
4) Saját REST szerveroldali implementációt írunk akár szerverrel együtt, ami támogatja a SEARCH methodot
Ja. Persze.

Kíváncsi vagyok a véleményekre. StackOverflown vannak megszólalások az ügyben, de nem tudnak meggyőzni egyik oldal igazáról sem. RFC-t hivatkozni pedig bárki tud.

Őszintén szólva nem látom a big picture-t, csak egyes elemeit értem. Magasabb szintű platformon dolgozok (ASP.NET MVC), és ennek a konvencióit követem, nem kellett még közvetlenül ilyenen gondolkodnom. Ez a REST dolog sok mindent takar, úgy látom, és ennek a GET/POST kérdéskör csak egy szelete. Szerintem attól még nem lesz rossz egy alkalmazás, hogy sok adatot GET helyett POST-ban küldesz egy kivételes esetben. A valódi problémák megoldásakor sajnos sokszor kell kerülő megoldás, és ettől nagyságrendekkel csúnyább szerintem, ha egy HTTP-nél (nem mondom, hogy tiltott, de) nem igazán jellemző dolgot művelnél.

--

Csak arra akartam felhívni a figyelmed, hogy elmúltak már a "há' baszd be posztba, aztán ott lesz a $_POST[] tömbbe'!" idők. Igen, a REST-nek nemhogy egy szelete a GET/POST kérdés, hanem egyáltalán nem arról szól. A lényeg viszont, hogy bár nem tiltott ez a GET-es payload, mégsem illik a konvenciókba. És nem(csak) történelmi okok miatt, hanem szemantikai miatt sem.

Nagy témakör ez a REST, gondolatformáló. Ha nem is használod, érdemes beletanulni bizonyos szintig.

Az nem megoldás, hogy egy POST-tal "létrehozol" egy Subgraph Search elemet, a válaszban pedig azonnal visszaadod az elemet (vagyis a találatokat)? Gyakorlatilag nevezéktanban módosítottad, de máris létrehozásról van szó (az már más kérdés, hogy nem perzisztens)

Szerk.: Most nézem, hogy ez gyakorlatilag a 3)-as csak egy kérésbe fogva (a 3-asnál te utána milyen url-en GET-elnéd az elvileg nem-perzisztens lekérdezési eredményt)? Ha máshol POST-ra nem adtok vissza eredményt, csak átirányítást, akkor nem játszik ez a megoldás, mert inkonzisztenssé teszi az API-t, de ha máshol is van ilyen, akkor működhet.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Minel egyszerubb, annal jobb, szoval en postolnam, nem fog elvinni a RESTful rendorseg. A masik fejlesztot csak az fogja erdekelni hogy konnyen tudja hasznalni az api-t es gyorsan tudjon vele fejleszteni. A doksiba bele kell irni a magyarazatot hogy miert dontottetek igy es kesz, senki nem fog ezen felhaborodni. A REST(ful) amugy sem egy hivatalos szabvany, de meg ha az lenne, akkor is azt csinalsz amit akarsz, ha van ertelme akkor senkit nem fog zavarni.

Ha létezik más lekérdezőnyelv is az URI + HTTP metódusok pároson kívül, akkor az az egész már nem RESTful igazából szerintem.

REST-nél minden létező entitást azonosít egy URI. A HTTP body data az entitás tartalmi leírására szolgál. Ebből következik szerintem, hogy ha RESTful szeretnél lenni, akkor a "legszebb" amit tehetsz, hogy magukat a lekérdezéseket is entitásként tárolod.
Legyen az URI namespace /query ezeknél, POST-tal létrehozod a query-t, a POST body tartalma maga a lekérdezés a megadott nyelven, majd a visszakapott query URI-n a queryURI/result URI-t GET-eled, ezzel megkapod az eredményt.

Tényleg érdeklődés szintjén: itt mi lenne a result URI? Egy nem perzisztens entitáshoz azonosítót rendelni csak azért, hogy GET-el leszedhető legyen nekem problémásnak tűnik (ha le van tárolva, akkor kell hozzá valami plusz időzített feladat, ami alkalmasint kiszedi a DB-ből azokat az azonosítókat, amiket a kliensek megkaptak, de soha nem töltöttek le), azonosító nélkül viszont marad a session/referer/akármi nézegetés, az meg nem REST.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Ha már nagyon RESTful akarunk lenni, akkor ez nem az :)
Inkább:

-> POST /api/query {"op":"AND", ch:["magas", "barnaszemű"]}
<- 201
Location: http://service/api/graph?q=154
{qid: 154, "op":"AND", ch:["kutya", "cica"]}

Plusz a visszaadott JSON nem hypertext, qid: 154 nem RESTful, {"_links": {"self": {"href": "http://...."}}, ...} vagy valami hasonló igen.
Általában minél szélesebb körben használják a service-t, annál jobban megéri törekedni a tökéletességre, de szerintem a sima POST -> response belefér ha pragmatizmus a mentség.

sőt, a qid köré idézőjelek kellenek, a visszatérő tömb sem csak egy tömb lesz, hanem egy objektumba ágyazott tömb, mitöbb, a státuszkódok mindenütt lemaradtak, de ha feltűnik, akkor nem is egy curl-ready queryt nyomtam be, hanem space-ekkel elválasztott példát, ami egy "->" szimbólummal kezdődik.

Röviden: ez nem ide tartozik, nyugodj meg, RESTfulak leszünk.

Nyugodt vagyok, nyugi :) REST náci sem vagyok, belső használatra simán írok RPC-over-HTTP service-eket :).
Az eredeti kérdést azért többször is el kellett olvasnom mire rájöttem, hogy a GET _request_-nek kell-e payload. Először nem értettem. Azután pedig azt hittem komoly a kérdés, hogy tényleg így oldalnád meg.
sorry.

GET /api/graph?q=154

Na igen, nekem pont ez a problémám. Ehhez a szerver oldalon valahogy tárolni kell a q=154 azonosítóhoz tartozó query-t, egy kérés idejére. Ami pl. azt is jelenti, hogy - ha tényleg stateless-ek akarunk maradni és felkészülni a terheléselosztásra - a szerverek közti közös adatelérési réteghez (memcache, adatbázis, akármi) hozzá kell adni. Viszont utána - felkészülve az API rossz használatára - kell egy külső folyamat, ami időnként törli az X időnél régebbi query-ket, hogy egy rosszarcú kliens ne tudja ledosolni a szolgáltatásunk azzal, hogy vadul refresheli a POST /api/query-t.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Pontosan erre gondoltam én is, ez a 2-es pontom. Aki posttal akar más bodyt küldeni egy resource endpointjára, az nincs tisztában a REST-tel.

Úgy látom viszont, hogy sajnos sok ilyen ember van stackowerflow-n is. Inkább lemondanak a RESTness-ségről, viszont úgy meg mi értelme az egésznek? Lehetne RPC-ként értelmezni, és elemezni a $_GET[]-et...

A 2 azért rossz, mert async módon csinálod a lekérdezést.

Kegyetlen mennyiségű megoldandó problémát veszel a nyakadba, szerintem csak akkor éri meg, ha a request futási ideje miatt kell. Ha bármi egyéb okból kell, akkor kerülném.
---
Régóta vágyok én, az androidok mezonkincsére már!

Rátapintottál a lényegre, bár ezt még érvként nem hoztuk fel, nyilván mivel többmilllió entitást tartalmazó gráfokról van szó, el fog tartani egy darabig, ilyenkor jól jöhet. Ha már itt tartunk, akkor OFF: a második lekérdezés ilyenkor valami olyasmivel kéne visszatérjen, hogy http status: "NOT READY", vagy ugye a leszűrt gráffal. NOT READY-t nem találok most hirtelen a státuszkódok között. Esetleg 206-Partial Content? (nem jó, mert nem partial, egyszerre vagy megvan a válasz, vagy nincs.) Esetleg 204-No Content? (Lehet, hogy a szűrésnek az eredménye az üres gráf, ez félreértést okozhat)

Ezzel nem értek feltétlenül egyet. Ha a query namespace-re küldesz aztán a /result-ra lekérdezést, akkor sem queryt, hanem graph entitást kapsz vissza, másrészt ha a /graph-ra küldesz egy olyat, hogy ?queryId=154, akkor kaphatsz vissza simán { queryID: 154, nodes: [...], edges: [...] } szerű választ... (mivel ugyebár szigorúan véve a lekérdezett subgraph sem egy perzisztált entitás, a teljes gráf egy részgráfja, tehát a lekérdezés után szerveoldalon meg is szűnhet létezni)

Szóval nem másik entitás id-jével paraméterezném, hanem úgymond foreign key-re szűrnék. Tehát nem /graph/:id lenne az URL-em sem, hanem /graph/?queryId=:id

"hanem graph entitást kapsz vissza"
Igaz az, hogy minden query eredménye létezik graph entitásként is? Ha nem, akkor nem igaz az, hogy graph entitást kapsz vissza, hanem egy graph entitással megegyező tartalmú "valamit". Ugyebár minden entitást címezni kell tudni és mindegyiknek kell legyen pontosan egy kanonikus címe.

Ha igen, akkor a /query/$qid/result átirányíthat egy /graph/$gid URI-ra.

"a teljes gráf egy részgráfja, tehát a lekérdezés után szerveoldalon meg is szűnhet létezni)"
Attól, hogy valami URI-n keresztül elérhető, nem jelenti azt, hogy perzisztens entitás lenne. Pontosabban a kliensnek nem kell tudnia, hogy az adott entitást épp akkor generálta a másik fél, vagy valamilyen perzisztens tárból húzta elő. Az a lényeg, hogy amikor futtat a kliens egy lekérdezést, kapjon valamiféle reprezentációt.

Ami viszont probléma, hogy egy entitás megváltozni elvileg csak és kizárólag POST hívásokkal tud, viszont a te esetedben ez nem áll fenn: amint megváltozik a megfelelő gráf, változik a query eredménye.

"/graph/?queryId=:id"
Bármelyik query bármelyik gráfra értelmezve van? Persze triviálisan lehet azt mondani, hogy igen, legfeljebb üres az eredményhalmaza, de pl. két különböző domain objektumok közötti kapcsolatokat leíró gráfok ne osszanak meg egymás között query-ket IMHO.

"Igaz az, hogy minden query eredménye létezik graph entitásként is?"
Igaz. Hogy a terminológia egyértelműbb legyen, nevezzük ezt akkor subgraphnak? Hm. az megint sok új dolgot vetne fel

"csak és kizárólag POST hívásokkal tud, viszont a te esetedben ez nem áll fenn"
Hát igen, az API többi része pont a gráf mókolását biztosíŧja. Na, hogy ezt hogy lehet szépen REST-esíteni, azt bevallom őszintén, _még_ nem tudom. Vagy ekkor tényleg fogjuk a jó öreg RPC-t? De ez már Off az Offban, szóval zárjuk is le. :-)

"Bármelyik query bármelyik gráfra értelmezve van?"
Egy gráf van igazából, mondhatni ez a gráf a valós rendszer globális állapotát hivatott reprezentálni.

Nos ez egy off szálnak indult (nem véletlenül, még mi magunk sem gondoltuk át), viszont ettől függetlenül köszönöm az új infókat, brainstormingot. Biztos, ami biztos, hétfőn leadom a rendelést a könyvre, ha még nem lenne meg.

Ha egy gráf van, akkor a /graph endpointnak IMHO nincs értelme, csak a /edge, /node, /query névtereknek.
A /query/$qid/result endpointra küldött GET-ek pedig linkekkel térnek vissza, amelyek /edge elemekre mutatnak (a node elemek implicitek).

Erre a három névtérre pedig fel lehet húzni egy RESTful API-t szerintem.

Mivel a query GET-ek problémásak (egymás után lekérdezve őket nem feltétlenül kapod meg ugyanazt az eredményt a többi módosítás miatt), akár verziózni is lehet a gráfot, és az eredményt cachelni. Amíg az új verzióra nem készül el a query eredménye, addig ki lehet szolgálni a régit, és jelezni egy mezőben, hogy ez outdated és majd lesz új.

Ezzel amúgy implementálni tudod azt is, hogy ha van egy gráf módosítás, de vannak futó query-k, akkor őket lelövöd, hiszen úgysem értelmes az eredményük.

Amúgy érdekes probléma a párhuzamosság itt:
mivel a query-k aszinkron futnak, vagy lockolják a gráfot, és addig a /edge és /node módosítások 503-mal térnek vissza, vagy valahogy kezeled azt, hogy query futás közben a gráf módosul és le kell lőni/újra kell indítani a query-t.

Amúgy már kész graph DB-ket nem néztetek meg, amelyeknek van REST API-ja? Az egyik legismertebb a Neo4J, ők szponzorálj(t)ák a DZone NoSQL zone-t.

1) Mi a baj vele. Nem pure REST, de hajrá pragmatizmus
2) Ha az overhead eltörpül a request/response payload és a feldolgozás ideje mellett, ezt választanám. Jól megírt (RESTful) _kliens_ számára transzparens az 1) és 2) közötti különbség ha a GET hívás blokkol.
3) Mitől jobb mint az 1)? Azon kívül hogy összezavar mindenkit aki REST-hez hasonló működésre számít.

edit: 0) pl. SPARQL

Amikor ilyen query-s dolgot művelsz, akkor az akárhogyan is csűröd csavarod, sehogy sem fér bele a klasszikus értelemben vett REST keretei közé.

Amúgy az egész felvetést nem értem. Megoldani szeretnéd a dolgot, vagy ideologizálni? Egyszerűbb nem lesz, ha URI binding-ot használsz, kevesebbet nem kell kódolni, és a supportja sem lesz olcsóbb. Ha 2-3 paraméternél összetettebb adatokat akarsz feltolni, akkor kár erőltetni, amibe nem fér bele. Az interfész doksijába valahogy mindenképpen le kell írni, akkor meg nem egyszerűbb azt használni, ami adja magát?

A magam részirül meg ha web/Java a téma, akkor fákk REST, én DWR-t használnék

A SOAPról bár nem beszéltünk össze, de érzésem szerint csakis érzelmi alapon zárjuk ki. Manapság ha publikálnánk egy SOAP-os XML-es api-t, az agilis nagyontrendi programozók többsége sikítófrászt kap. Én is.

A linkelt SO választ már megtaláltuk, sőt, az ilyenek alapján jutottunk el a SEARCH http methodhoz. :-)

Hát te tudod, hogy milyen fogadóközönséggel kell lenyeletni a produktumot, de az finoman szólva nem lenne valami "professzionális", ha érzelmi alapon elutasítanátok a műszakilag (esetleg?) jobban megfelelő alternatívát.

Ha már sikerült tervezni valami nagyon bonyolultan használható dolgot, akkor nem lesz könnyű dolga a kliens oldalnak egyik megoldás esetén sem. Én a helyedben azt a megoldást választanám, amit nekem könnyebb megcsinálni. :)

(Mondjuk első körben azért elgondolkodnék azon, hogy egyáltalán jól van-e megtervezve az interfész vagy az egész szolgáltatás?)

Nemcsak érzelmi kérdésről van itt szó. 2014-et írunk. Senki nem XML-lel akar szopni, senki nem SOAP-ozni akar, hanem nagyonfenszi weblapokon curl-lel működő példákat akar látni.

SOAP-oztam is, JSON-RPC-ztem is, GWT-RPC-ztem is, mitöbb, még gy pillantást a protobufra is vetettem. Ezek alapján azt hiszem kellően kifejtettem, hogy az "érzelmi" alapok igazából szakmailag alátámasztottak. A letöbb developernek viszont már nem kell ecsetelni, hogy miért ne ezeket használjuk, egy egyszerű "broáf"-fal megértik, mire gondolunk. A REST nemcsak szerintem, de a projekt többi tagja szerint is a befutó.

(Amúgy a GWT-RPC-t nagyon is élveztem annó, kényelmes és gyors volt használni)

Ideológiailag a GET-be tett bodyt éppúgy megvetik mint POST-tal való lekérdezést - szóval ezt ezen az alapon nem fogod tudni eldönteni. Bármelyiket csinálod a kettő közül mindenképp leköpnek! ;)

Marad az egyszerűség és a támogatottság - ami alapján meg marad POST (feltéve ha 1.-es megoldás meg kiesik a hosszkorlát miatt!).

Támogatottság alapján az értem, hogy hiába nem tilos, senki sem számít GET body-ra, meg a "be liberal in what you accept, and conservative in what you send" stb...

Végül, jöjjön minden ideológiai vita csúcspontja az argument from authority, Roy T. Fielding írja:

Yes. In other words, any HTTP request message is allowed to contain
a message body, and thus must parse messages with that in mind.
Server semantics for GET, however, are restricted such that a body,
if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.

So, yes, you can send a body with GET, and no, it is never useful
to do so.

This is part of the layered design of HTTP/1.1 that will become
clear again once the spec is partitioned (work in progress).

https://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/9…
(a kiemelés tőlem...)

Hát nem tudom. Nekem a GET-be payload kisebb gondnak tűnik. Mivel a HTTP-ben van rá lehetőség, és restful is maradna. És még mások is csinálják. Az api-docban pedig leírják, hogy működik (lásd pl. ezt)

Viszont POST-tal nem kompatibilis entitást posztolni endpointra, úgy pont a REST lényege veszik el. És ezt hiába is próbálnám meg az api-docban megmagyarázni, a POST-ot rosszul használva komolytalanná válik az egész.

1. Szerintem nem maradna restful, mivel nem az URI írja le az entitást, amit visszakapsz. (Itt sérti a RESTful szabványt)
2. Mivel a GET-hez elvileg nem tartozhat body, ezért problémákba ütközhetsz bizonyos programok használatánál, amik ezt nem támogatják (browser, proxy, web szerver). (Itt sérti a HTTP szabványt)
3. Mivel nem az URI írja le, azt, amit visszakapsz, ezért a cache-sel is problémák adódhatnak. (Itt is sérti a HTTP szabványt, a GET safe method, cachelhető)

Szerintem a POST jobb megoldás és szerintem még RESTful is marad. Egy entitást átadsz és "létrehoz" egy új entitást (nem tárolja), ami a lekérdezés eredménye.
pl. a /graph-query entitás példány

Szerintem ;)

1) GETelni a /graph-ra mennek, es a query menne a bodyban, szoval az URI irna le az entitast.

2) A GET elvileg is tartalmazhat bodyt.

A message-body MUST NOT be included in
a request if the specification of the request method (section 5.1.1)
does not allow sending an entity-body in requests. A server SHOULD
read and forward a message-body on any request;

Többit megtalálod ott, a lényeg, hogy az 5.1.1-ben nincs tiltva, illetve a GET szemantikájánál sincs (9.3 GET) tiltva.

3) 1)-es pontban tisztáztam.

Ha a /graph-ra posztolok egy "query" entitást, akkor az minden csak nem RESTful.

Látom nem olvastad el a REST (és jó részben http) kitalálójának magyarázatát...

Lefordítom:
A szintaktika és szemantika külön van választva, a szintaktika egységes: minden http-nek lehet bodyja

De a szemantika ezzel szemben pedig az, hogy a GET bodyja nem befolyásolhatja a szerver válaszát! Tehát 1-3-ig (csökkenő ideológiai szigorúság szerint sorrendezve):

1. A hivatalos RESTful megoldás PUT-tal (és azért nem POST, mert ezt idempotensen is lehet) filter létrehozása, és annak lekérése egy GET-el.

2. Ha szarsz a REST-re akkor egy darab POST.

3. Ha szarsz a http-re is, akkor meg mehet a GET bodyval.

(Analógia: olyan ez mintha egy programnyelvet úgy terjesztenél ki, hogy a kommentjeit is el kezded értelmezni méghozzá oly módon, hogy az érdemben befolyásolja a program futás EREDMÉNYÉT, de az ilyen hozzáállás csak addig ok amíg nem befolyásolja a futás eredményét (pl. párhuzamosítás, verifikáció, típusinformáció, optimalizáció stb.. céljából lehet ilyen kiterjesztést tenni egy prog. nyelvhez - az sem feltétlen szép mondjuk)

Félreértés ne essék, én sem támogatom a body-t a GET-hez, viszont a többi workaroundot még nagyobb konvenciósértésnek érzem. A legtöbben SO-n sem linkelnek bizonyítékot, csak magyaráznak- Eközben pedig vannak libek, amik úgy lettek megírva, hogy a GET-be payloaot várnak...

"a többi workaroundot még nagyobb konvenciósértésnek érzem"

Hát én máshogy érzem. Meg is indokolom.

Programnyelvi analógiában: a POST használata GET helyett olyan mintha lehagynád egy olyan C++ metódus végéről a const kulcsszót ami pedig nem is módosítja az objektumot, vagy IO monádban implementálnál egy mellékhatásmentes függvényt Haskellben, stb...

A get-be tett body ezzel szemben meg olyan mintha egyszer csak elkezdenéd futtatni a kommentbe tett kódsorokat is.

"sem linkelnek bizonyítékot, csak magyaráznak"

Itt alattam hivatkoznak az RFC-re. Magyarázat meg az érvelés azért csak számít valamit. Jelen esetben az érv - ami alapján én máshogy "érzem" mint te - annyi, hogy azt kell végiggondolni milyen hibát okoz ha X résztvevő nem tud a speciális konvenciódról:

1. Az első esetben azt várja, hogy állapotmódosulás történjen de nem fog (de a 0 állapotmódosulás része az összes állapotmódosulások halmazának - ezért a várakozás tágabb értelemben nem hiúsul meg)

2. A második esetben azt várja hogy semmi se történik, de mégis történik valami (mivel a valami nem részhalmaza a semminek - itt a felhasználó alapértelmezett várakozása nyilvánvalóan meghiúsul)

Igen, tartalmazhat body-t, de a GET eredmenyekeppen az nem veendo figyelembe, a szerver csak es kizarolag a Request URI-t kell figyelembe vennie az entitas kiszolgalasahoz.

"The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI."

Ezen kivul meg vannak mas szemantikai esetei a GET-nek (partial GET pl.), de azok is mind csak headerektol fuggnek.

Szoval a GET body ilyen ertelemben olyan, mintha /dev/null-ba kuldened.
Peldaul a Jetty servlet container figyelembe sem veszi a GET body-t.

A gyakorlati megvalósítások - ahogy most már látom - valamelyike elfogadja, valamelyike nem. Ileltve a proxyzás megintcsak gond lehet. Szóval a praktikum ezek alapján győzött a szépség felett részemről.

Mivel még csak prototipizálunk, nem most kell kimdent megoldanunk, de a végleges termékben azért mégegyszer nekifotnék annak, ha nem RESTful POSTolounk.

Ez nem csak praktikum vs. szépség. A GET szemantikájában jól definiált, hogy a body-nak nem szabad, hogy köze legyen az entitáshoz. Csak és kizárólag a request URI számít.

Azaz pont az egész szépsége borulna azzal, ha GET body-t használnál.

OFF:
Ez a jóra való RESTség?

1) Lehet, hogy én vagyok értetlen, most akkor ezt hogyan is képzeled? Eddig nekem az volt a fejemben, hogy két lekérdezés pl. ilyen:
GET /graph { lekérdezés1 body }
GET /graph { lekérdezés2 body }
Itt gondolom mást ad vissza az 1-nél és mást a 2-nél. Ekkor viszont az URI (/graph) nem írja le az eredményt.

2) Ebben nem voltam biztos, hogy a szabvány se engedi, vagy csak bizonyos programok nem támogatják, de browser-nél már mintha találkoztam volna, hogy nem engedi, illetve hallottam ilyet. Minden estre szerintem a rizikó benne van.

3) Nem tudom melyik 1)-re gondolsz. Ezért is írtam /graph-query-nek, mert ez nem egy /graph
Tehát a /graph-ba mehet a post, put, get, delete, a /graph-query-be meg egyedül a speciális lekérdezések post-ja, ahol vagy visszaadod a letárolt query azonosítóját és majd get-tel elkéred az eredményt, vagy egyből az eredményt adod vissza.
Szerintem mind a kettő restful, de ha adtok linket, hogy a POST-nál a létrehozott entitást visszaadni nem RESTful, csak az id-jét, akkor azt is el tudom fogadni.

Más. Szerintem POST és nem PUT, mivel a PUT-nál az URI a módosítandó entitást azonosítja, POST-nál pedig csak az osztályát (típusát).

1) Igen, erre gondoltam, és tény, hogy nem írja le az URI az eredményt. Tehát hogy pontosítsak: a body csak és kizárólag azért küldjük, mert a queryparamba talán nem férne el.
2) A szabvány... hát... mondjuk úgy: nem tiltja. Ahogy persicsb is kifejtette, előfordulhat azonban, hogy az alattunk levő szerver implementáció nem támogatja, nem adja tovább.
3) Igen, ezt is hasonlóan gondoltam. A második részét a mondatodnak nem értem. POSTnál - szerintem - a létrehozott entitást visszaadni igenis RESTful (ugye az id-vel együtt), de lehet, hogy rosszul tudom.

És igen, mi sem PUT-ra gondoltunk.

A szabvány valóban nem tiltja a GET bodyt, de azt kifejezetten leírja, hogy a body nem vehető figyelembe a GET eredményének elkészítésekor, csak és kizárólag a Request-URI számít.

Szóval az teljesen normális viselkedés, ha a HTTP lib implementáció nem fog továbbítani neked GET body-t, helyesen jár el.

Ok.

Nem olvasom végig, de gondolom ezek jó része amúgy is akkor számít igazán, ha nem hagyományos QOS nélküli TCP/IP felett fut a dolog.

Egy best-effort szemléletű hálózat feletti alkalmazásban ugyanis eleve semmiféle szemantikai hibát nem okozhat a válaszok kis mértékű nem determinisztikus késleltetése. Ezzel eleve számolniuk kell. Pl. mondjuk ha egy GET request átlag 50ms késleltetést szenved el a szerveren azért mert én mondjuk csak minden 100. ms-ben vagyok hajlandó frissíteni a cache-t az adott (mondjuk rendkívül népszerű) URIhoz azaz a következő "kört" kiváratom requestekkel

"Nem olvasom végig, de gondolom ezek jó része amúgy is akkor számít igazán, ha nem hagyományos QOS nélküli TCP/IP felett fut a dolog."
Nem, baromira nem erről van szó.

A HTTP-t nem érdekli az alatta lévő transzport milyensége. És ez így van jól (absztrakció, anyone?).

A HTTP caching arról szól, hogy meddig érvényes az adott entitás. Ha az érvényességi időn belül vagy, bármelyik fél nyugodtan cache-lheti (kliens, proxy, bárki).
Míg ha lejár az érvényességi idő, úgy törölni kell a cache-t, és újra lekérni az entitást.

3) Akkor ezt próbálom kicsit jobban megmagyarázni.
Vannak a /graph entitások, ezek, ha jól értem, a teljes, hatalmas gráfok.
Ebből szeretnétek lekérdezni egy részgráfot. Mivel a lekérdezés paraméterei is bonyolultak és terjedelmesek, emiatt egy "entitás"-t használnátok a megadására (lekérdezés entitás). Ezt berakhatjátok a /graph-query alá POST-tal, letárolhatjátok, az azonosítóját visszaadjátok, majd egy GET-tel elkérhetitek. Ez az eredeti 2) eset. Ha itt nem (csak) az azonosítóját adjátok vissza, hanem az entitást (is), akkor nem kell letárolni. Ez a 2)-es eset speciális változata, ez az eredeti 1)-es eset.

Itt szerintem az okoz félreértést, hogy az entitás létrehozásához megadott adatok nem ugyanazok, mint a létrejövő entitás, azok csak a létrehozásukhoz kell. A legtöbb esetben a megadott adatok majdnem ugyanazok, mint a létrejövő entitás, legfeljebb egy ID-t kap (vagy még azt sem). Tehát itt nem a lekérdezés paramétereit akarod létrehozni, hanem a részgráfot, amiatt a /graph-query helyett jobb is lenne pl. /part-graph-nak hívni.

Példa 2-es esetre (POST+GET):
létrehozunk egy növényt:
POST /noveny { param: "makk" } => Created, Location: /noveny/154
lekérjük:
GET /noveny/154 => Ok: { nev: "Tölgy", tipus: "fa" }

1)-re (POST)
POST /noveny { param: "makk" } => Created: { nev: "Tölgy", tipus: "fa" }

Talán így szemléletesebb, mint gráfokkal.

Ha távol van a kliens (nem mondjuk intranetről van szó), akkor lehet hogy olyan proxyn keresztül konnektál, ami nem számít rá, hogy GET-nek bodyja van, és nem is továbbítja. Én kerülném.

A HATEOAS-t hogy oldjatok meg json valaszban?

En is ellene vagyok a GET bodynak, akkor is, ha a HTTP szabvanyba belefer. Nem lehet a graf resource-hoz egy kulon search actiont adni? Rails eseteben pl. van arra lehetoseg, hogy a RESTful utak mellett plusz actiont is adjunk a collection-hoz, pl: /graphs/search. Mivel ez mar nem resze a RESTful utaknak, igy nem is kell feltetlenul ragaszkodni a RESTful szabvanyhoz, siman lehet ra POST-olni.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. 

Nem olvastam végig az összes hozzászólást, ha valaki írta már akkor sry.

Nyilván a kis "labor" környezetedben gond nélkül működhet a GET bodyval, viszont ha egy kicsit is komolyabb infratruktúrába helyezed a szoftveredet, akkor lehetnek elég nagy meglepetések. Mindenféle WAF (Web Application Firewall) eszközök simán dobhatják az ilyen nem szabványos GET kéréseket és valószínűleg nem fognak örülni neki az üzemeltetői, ha miattad kell adott esetben kikapcsolni, vagy gyengíteni a szabályokon. Ha egyáltalán lehet.

OK, köszönöm a hozzászólásokat, arról meg lettem győzve már, hogy a GET+body nem jó ötlet, de arról nem, hogy a POST jó lenne.

Szóval pontosan ahogy mondod, most inhouse játszadozni jó lesz a GET/POST-os gánymegoldás, aztán RESTesítünk/RPC-sítünk majd a későbbiekben.