ugrás a tartalomhoz

REST service & client uri milyen legyen?

inf · 2013. Ápr. 20. (Szo), 02.16
Sziasztok!

Szerintetek egy REST service-nél, ha single page kliens van, és pushState-el frissítem az uri-t, akkor annak milyennek kellene lennie?

Egyelőre az van eldöntve, hogy a kliens és a service külön erőforrás alatt (külön mappában vagy subdomain-en) lesz. Amin most agyalok, hogy a kliens erőforrásai és a service erőforrásai tökéletes tükörképek legyenek e, vagy sem. Illetve, hogy milyen mélységben érdemes a kliens állapotát az url-ben jelölni.

pl:
service - felhasználói adatok:
GET service/users/inf3rno

client - profil oldal:
GET client/users/inf3rno
GET client/users/inf3rno?profile
GET client/users/inf3rno/profile
GET client/users/profile?name=inf3rno
GET client/profile?name=inf3rno
GET client/profile/inf3rno
GET service/users/inf3rno/profile

Szerintetek melyik a helyes?

A users/inf3rno teljes szinkronban van a service-es url-el, de nem jelöli, hogy a felhasználónak a profil oldalán vagyunk. Lehetnénk akár a felhasználói adatok szerkesztésének az űrlapján is, vagy bárhol máshol. Rosszabb helyeken összemossák a kliens-t a szerverrel ebben az esetben, és beteszik a service-be egy külön erőforrásba, mint én az utolsó példánál.

Szerintetek szükség van arra, hogy minden olyan aloldal külön url bejegyzést kapjon, ami szorosan kapcsolódik egy erőforráshoz? Pl: profil oldal / adatok szerkesztése oldal - mindkettő ugyanarra az erőforrásra vonatkozik... Vagy felhasználók listázása különböző limittel és rendezési móddal...

Ha szükség van minden egyes aloldal jelölésére az url-ben, akkor szerintetek a fentiek közül melyik a helyes forma? Muszáj megtartani a service eredeti struktúráját, vagy jobb eltérni tőle, és ha igen, akkor milyen mértékben?
 
1

Azt hiszem ez ugyanaz a

inf · 2013. Ápr. 20. (Szo), 02.59
Azt hiszem ez ugyanaz a probléma, amibe régebben is belefutottam, csak más köntösben. Ott még a statikus html támogatása is kérdés volt, meg a service és a client is egyben volt. Ott sem jutottam igazán megoldásra, max arra, hogy egy oldalon jelenítek meg mindent, így nem kell az aloldalakat külön letárolni az url-ben. Ez viszont nem lenne túl szép. A másik változat az volt, hogy header-ben kell átküldeni az adatot, de ott nem gondoltam eléggé át, hogy az állapotot is le kell tudni írni, így csak az url a megfelelő forma.

Jelenleg én úgy állok, hogy az összes aloldalnak meg kell jelennie valamilyen formában az url-ben. Az ilyen aloldalak mind csak GET-es erőforrások. A client-hez tartoznak szorosan, de kapcsolatban vannak a service-ben lévő erőforrásokkal is. Ezeknek kellene valahogyan megjelenni az url-ben.

A sort és a limit egyértelműen queryString után kell, hogy jöjjön, ez legalább letisztult közben. Hash-t nem lehet használni, hogy kompatibilis legyen a pushState nélküli változattal. Header-t sem lehet használni, mert nem az url része, ahogy külön method-ot sem, szóval azok kiestek. A queryString sem jó szerintem, mert az erőforrás szűrésre, rendszerezésre, stb jó, itt viszont az erőforrás, amihez kapcsolt a dolog nem változik.

Így ez a három jelölt maradt:
GET client/users/inf3rno/profile
GET client/users/profile?name=inf3rno


Az elsővel az a baj, hogy a rest service szerinti megközelítés az egyre szűkíti az adatokat:

users : felhasználók listája
users/inf3rno : inf3rno nevű felhasználó
users/inf3rno/email : inf3rno nevű felhasználó email címe
users/inf3rno/email/host : email szolgáltató
....

a profile nem szűkít adatot, sőt nincs is ilyen tulajdonsága az felhasználóknak, tehát nem stimmel.

Ezzel a logikával viszont bejött két újabb:

GET client/users/profiles/inf3rno
GET client/profiles/inf3rno


Ezeknél ugyanaz a helyzet, mint az előzőnél: az inf3rno-nak semmi köze nincs a profil oldal tulajdonságaihoz, mert adat azonosító.


Szerintem ezek a megoldások elfogadhatóak (a saját REST-es elképzeléseimmel):
GET client/users/profile?name=inf3rno
GET client/users/inf3rno?page=profile
GET service/users/inf3rno?page=profile


Az első változat, ami szerintem a helyes, mert hasonló a profile-userData és a users-sort viszonya. A másik két megoldás, ami inkább megszokott, de mégsem keveredik bennük a path-ban az erőforrás és a pluszban felhasznált adat.

Jelenleg olyan szerencsés helyzetben vagyok, hogy az url kinézete nem számít, úgyhogy az első változatot fogom alkalmazni. Ha számítana, akkor meg a megszokott lenne egy kis módosítással:

GET users/inf3rno?page=profile


Az hiszem olyan helyzetben, ahol több erőforrást jelenítünk meg egyszerre, mindig választani kell egy fő erőforrást, amit beteszünk a path-ba, a mellék erőforrásokat pedig betehetjük nyugodtan a queryString-be.

Mint most kiderült, alapvetően a kérdés két erőforrás egyszerre történő megjelenítésére vonatkozott:
client/user/profile
service/users/inf3rno

Az egyik az adat szolgáltató, a másik a megjelenítő, és ha history-ba akarunk menteni egy állapotot, akkor mindegyiket kénytelenek vagyunk az url-be tenni.

Ezek alapján a legmegfelelőbb leírási forma:
service/users/inf3rno?client/user/profile

Csak kibogoztam :D

Ismét sikerült megválaszolnom a saját kérdésem :D
Amúgy érdekel, hogy ti mit gondoltok a témáról, sokan a múltkor sem értették, hogy mit szöszölök ennyit az url-eken :D

Egyébként ezért nincs szerintem még REST szabvány, mert ilyen ellentmondások vannak a rendszerben. Én amit eddig REST-ről láttam, abban az volt, hogy path - erőforrás, queryString - kérés leírása (sort, limit, keresőkifejezés, stb...), header - megjelenítési mód, pl accept header-ben az elvárt mime típus küldése. Ennél a history-s problémánál viszont csak az url-t lehet felhasználni, és a megjelenítési módot is abban kell átküldeni, nem pedig header-ben, úgyhogy ez a változat is bukott egészen addig, amíg nem építik be a böngészőkbe, hogy a history bizonyos az aktuális állapottal kapcsolatos header információkat is letároljon. Szerintem még jó darabig nem lesz ilyen, úgyhogy REST szabvány sem, vagy ami lesz, ott biztos, hogy az url valamelyik részét egynél több dologra fogják felhasználni.
2

Közben találtam egy mégjobb

inf · 2013. Ápr. 20. (Szo), 05.54
Közben találtam egy mégjobb megoldást:

GET user/1
GET user/1?calls=update
UPDATE user/1
DELETE user/1

GET user
GET user?calls=create
CREATE user


Általában egy UPDATE-hez vagy CREATE-hez csak egy bizonyos típusú űrlap küldi az információt, illetve egy erőforrást csak egyféle sablonnal jelenítünk meg (ha leszámítjuk az accept header-hez kapcsolt dolgokat, vagy a munkamenetben tárolt skin-t). Szerintem ez az esetek 99%-ában működni fog, úgyhogy inkább ezt használom.

Tovább tákolva ezen, lehet reserved word-öt is csinálni:

GET user/1
GET user/1/UPDATE
UPDATE user/1
DELETE user/1

GET user
GET user/CREATE
CREATE user
3

Pontosítanál egy kicsit?

T.G · 2013. Ápr. 20. (Szo), 07.00
Szerintem én is azok (népes) táborát képviselem, akik előszeretettel használják a RESTful kifejezést saját alkalmazásukra, de biztos hamar zavarba lehetne hozni, hogy ezt meg azt miként valósítom meg... :)

A probléma felvetést én nem értem. Pontosan mit értesz az alatt, hogy a kliens erőforrásait és a service erőforrásait különválasztod? Adott két url, ezekre milyen választ vársz, és ki hívja meg őket?
GET service/users/inf3rno
GET client/users/inf3rno

A 2. hozzászólásodat nehezen értelmezem, a következő kérés nekem nagyon idegen:
GET user/1?calls=update

Ez pontosan mit is csinál? :)
4

A probléma felvetést én nem

Poetro · 2013. Ápr. 20. (Szo), 10.42
A probléma felvetést én nem értem. Pontosan mit értesz az alatt, hogy a kliens erőforrásait és a service erőforrásait különválasztod?

Egyáltalán miért választod őket külön URL-re? Miért nem lehet azonos URL-en kiszolgálni őket más Accept fejléccel?
5

Elég szimpla, a service csak

inf · 2013. Ápr. 20. (Szo), 16.06
Elég szimpla, a service csak adatot szolgáltat JSON formában, illetve adatot tárol le, amit JSON formában küldesz el neki. A kliens single page weblap, ami a service-t használja adatforrásnak, tárolónak, de akár a client lehetne mondjuk egy java alkalmazás, vagy bármi más is, ezért gondoltam, hogy külön szedem az url-jüket. Amit a felhasználó lát az csak a kliens url-je.

A calls=update az calls=put akart lenni leginkább. Kb annyit jelöl, hogy űrlapról van szó, amivel PUT kérést lehet végrehajtani. Ilyen űrlap meg általában csak egy szokott lenni egy erőforráshoz, azért használható ez a megközelítés az esetek döntő többségében. További előnye, hogyha kliens oldalra lemásolod, hogy mire van joga a felhasználónak, akkor az ilyen típusú linkeknél kapásból meg tudod nézni az erőforrást, és azt, hogy put-ot akar használni, és kiírod, hogy nincs joga a művelethez. Szóval már eleve az űrlap sem fog lejönni. A calls helyett uses vagy sends vagy method, vagy valami ilyesmi kifejezés kellene, maga a calls az szerintem nem a legjobb szó, de még nem találtam meg az igazit.

Visszatérve, az alap probléma elég egyszerű, arról van szó, hogy van egy adatforrásod és van több megjelenítőd, ami ugyanazt az adatforrást használja. Hogy írod le ezt url-ben úgy, hogy a path részben csak az adatforrásod szerepelhet? Nyilván a queryString-be fog menni minden más...

Még valaki közületek belinkelt egy video-t a REST-ről, ami alapján próbáltam elindulni:

http://munich2012.drupal.org/program/sessions/designing-http-interfaces-and-restful-web-services

Sajnos a benne lévő állítások, bár szépek, de nem lehet rájuk alapozni, mert az aktuális oldalt csak url-el lehet leírni, és az aktuális oldal megjelenítése (amit ők header-be raknának) is az url-be kell, hogy kerüljön.

Ezt az egész ellentmondást egyébként fel lehet oldani úgy is, hogy az adatszolgáltató egy REST service, ami megfelel az ott leírt elveknek (path - erőforrás, queryString - lekérdezés módosítók, header - megjelenítés, method - mit csinálunk), a hozzá tartozó kliens az url-eket tekintve meg egy hagyományos webalkalmazás. Szóval ezekkel a REST alapelvekkel, amik egyébként elég logikusak, nem lehet leírni klienseket.
6

Összefoglaló

inf · 2013. Ápr. 20. (Szo), 17.39
Összefoglaló:

Ha ezeket tekintjük REST alapelveknek:
- a http kérés minden része csak egy témakört ír le
- method : action, amit hívunk az erőforrásra
- path : az erőforrás azonosítója
- queryString : lekérdezés módosítók, pl: sort, limit, filter, stb...
- headers : megjelenítés módosítók, pl: accept: text/html, stb...

Akkor a jelenlegi technológiával csak adatszolgáltató hozható létre. Klienseket nem lehet létrehozni ezekkel az alapelvekkel, mert a kliensek url-jében szerepelnie kell a megjelenítés módosítóknak ahhoz, hogy a vissza gomb működjön. Szóval a kliensek továbbra is hagyományos webalkalmazások lesznek. Lehetőség van arra, hogy a klienst és az adatszolgáltatót egybeolvasszuk, mert az alapértelmezett megjelenítés módosítót nem muszáj betenni a kliens url-jébe:
users/inf3rno + templates/profile.tpl -> users/inf3rno/profile -> users/inf3rno
users/inf3rno + templates/edit.tpl -> users/inf3rno/edit

vagy
users/inf3rno + templates/profile.tpl -> users/inf3rno?form-type=GET-> users/inf3rno
users/inf3rno + templates/edit.tpl -> users/inf3rno/?form-type=PUT

Így a normál megjelenítés lesz mindig az alapértelmezett, az űrlap meg a másodlagos forma.

Lehetőség van arra is, hogy az űrlapokat nem tesszük lapozhatóvá:
users/inf3rno + templates/profile.tpl -> users/inf3rno
users/inf3rno + templates/edit.tpl -> users/inf3rno

Így csökken a felhasználói élmény, de a kliens meg fog felelni a REST szabályoknak.

Lehetőség van arra is, hogy ezeket a REST szabályokat megváltoztassuk. Így a http kérés egy része több témakört leírhat, pl a queryString egyszerre leírhatja a lekérdezés módosítókat és a megjelenítés módosítókat. Ennek nyilván az az ára, hogy kevésbé lesz rendezett a REST service-ünk.


Én azt hiszem, hogy a klienseimet hagyományos webalkalmazásokként fogom leírni ezentúl, és teszek beléjük egy mapping-et, ami a webalkalmazás url-jét átalakítja az adatszolgáltató url-jére:
GET client.uri -> METHOD service.uri
GET users/inf3rno -> GET users/inf3rno
GET users/inf3rno/edit -> PUT users/inf3rno

Azt hiszem ez a legátláthatóbb forma, mert az url ugyanolyan lesz, mint megszoktuk, viszont a REST szabályok sem sérülnek tőle, mert tisztáztuk a kódban, hogy a kliens nem REST service, hanem sima webalkalmazás. A kliens-ben egyébként is csak GET meg POST van, ami már elve nem felel meg a REST követelményeknek...
7

Okosabb kliens?

T.G · 2013. Ápr. 20. (Szo), 18.47
Én csak azt az egyet nem értem, hogy miért akarsz ennyire "buta" klienst?

Szerintem semmi baj nincs azzal, ha a kliens először lekéri az adatokat, majd lekéri a sablon fájlt és a kettőből állítja elő a megjelenítésre szolgáló tartalmat. Ahogy az üres űrlapot is lekérheti, illetve az előzőleg kapott adatok meg megjelenítheti ebben. Szerintem közelebb vagyunk a szabványhoz, ha nem egy, hanem három erőforrásról beszélünk:
GET /user/1
GET /template/profile
GET /form/profile

És, még csak azt az irányelvet sem kell felrúgni, hogy az üzenetek önleírók legyenek, mert az első üzenet tartalmazhatja a második kettő url-jét. Akár a fejlécbe, akár a tartalomban. (ahogy a HTML oldal is tartalmazza a CSS fájl elérhetőségét, amit a böngésző egy külön kérésként hoz le, megjelenítés során meg természetesen felhasználja azt)

Szerintem túlságosan ragaszkodsz a különböző url ajánlásokhoz, miközben (tudtommal) a REST ezekre egyáltalán nem tér ki. Ha megnézed a különböző kliens oldali framework-ökhöz készült REST leírásokat, akkor az első helyen szerepel, hogy miként írhatod át az url-eket a saját igényeid szerint. Hogy ne mindig az ExtJS-t említsem, Backbone-ban Backbone.Model.methodToURL
(félreértés ne legyen, nagyon hasznos, ha az url szép, illetve logikusan épül fel, de a szabvány erről nem szól)

Megjegyzés: Az Ajax hívásnál adhatsz meg PUT illetve DELETE típust, az működni fog.
8

Haha, nem ment át még mindig.

inf · 2013. Ápr. 20. (Szo), 20.37
Haha, nem ment át még mindig. Persze, hogy lehet okos a kliens, a gond az, hogy a legtöbb felhasználó a hozzászokott a history-hoz, és használja a vissza és előre gombokat, így a kliens minden állapotát (minden aloldalt, ami megjelenítéssel foglalkozik) be kell tenni url-be, mert a history csak azt tárolja le. A te példád nem stimmel, mert sablonnal aloldalanként ott két erőforrás van:

GET /user/1
GET /template/profile

és
GET /user/1
GET /form/profile


A history miatt sajnos minden ilyen aloldalhoz rendelni kell 1-1 url-t. Ennek az url-nek a tulajdonságai, amik érdekeltek, de ezeket már nem lehet úgy belőni, hogy az általáam elfogadott REST normáknak megfeleljenek.

Én egyébként nem sablonnal oldom meg, hanem különböző keretrendszerekkel és laconic-ot használó saját osztályokkal, szóval egyáltalán nem buta a kliensem. Egyszerűen, ha a kliensed webalkalmazás, akkor nem tud megfelelni a REST-es elvárásoknak az url struktúrája. Ha meg valamilyen asztali alkalmazás, akkor meg eleve nincs is benne url.

Szerintem egyébként túlvariálom, túl tökéletesre akarom megcsinálni :D

Btw egy aloldalhoz a kliens-ben, tehát egy kliens url-hez több adatforrás is tartozhat, szóval eleve rossz az a logika, hogy a REST service url-jeit próbálom megfeleltetni a kliens url-jeinek. Jobb inkább egy proxy-t csinálni a Service-ről, ami tárolja az erőforrásokat és method-okat, és annak átadni az adatot, illetve attól elkérni. Legközelebb majd megpróbálom ezt inkább itthon végiggondolni, mint hogy blogot írjak weblaborra :D
9

csak a kommunikáció!

T.G · 2013. Ápr. 20. (Szo), 21.21
Az én elképzelésem szerint az összes REST hívás háttérben futó Ajax hívás, az hogy mi van a böngésző url-jében az teljesen független ettől. Ezt JS-sel kell lekezelni függetlenül az előbbitől.

Mi csak a szerver-kliens kommunikációról beszélünk, a kliens viselkedése szerintem nem része annak, hogy REST vagy nem REST...
10

Így van, de fél év kellett,

inf · 2013. Ápr. 20. (Szo), 21.37
Így van, de fél év kellett, hogy rájöjjek :D Az volt a gond, hogy az anyagok, amiket olvastam a hagyományos webalkalmazásokból indultak ki, és megfeleltették a kliens url-jét a rest service url-jével, holott nagyon nagy a különbség, és nem lehet egy lapon említeni a kettőt. Azt hiszem majd írok egy blog bejegyzést erről. Mondjuk már több cikk van, amivel adós vagyok, egyszerűen nincs időm most írni, csúszásban van a projekt :S
11

Kiszórtam külön subdomainekre

inf · 2013. Ápr. 21. (V), 03.16
Kiszórtam külön subdomainekre a klienseket, így már tényleg sokkal tisztább. Király! :-)
18

Szavadon foglak

Pepita · 2013. Ápr. 21. (V), 17.44
Azt hiszem majd írok egy blog bejegyzést erről.
Várom! Az adósságokat behajtjuk, kifogásokat nem fogadunk el! (Remélem lesznek akik mellém állnak, ezért a többes szám.)

:)
19

Jóvan, ha jönnek a

inf · 2013. Ápr. 21. (V), 20.55
Jóvan, ha jönnek a verőlegények, legalább tudom ki küldte őket :D
22

Nem vagyok én olyan...

Pepita · 2013. Ápr. 23. (K), 11.40
Nem vagyok én olyan... Nem fogod tudni, hogy én küldtem. :)
12

Azt hogy szoktad kikerülni,

inf · 2013. Ápr. 21. (V), 06.54
Azt hogy szoktad kikerülni, hogy MSIE egy határ szar? Belefutottam abba, hogy cross-domain kérésekhez használhatatlan, amit nyújtanak, olyan, mintha nem is lenne... Ez körülbelül az 50. alkalom, hogy a microsoft termékei kiakasztanak, lassan már ünnepelni lehet...

Elméletileg IE10 már támogatja rendesen ugyanazt, mint firefox és a többi. Most választhatok, hogy nem támogatom IE6, IE7, IE8, IE9 -et, vagy almappákba teszek mindent subdomain helyett. Egyelőre maradni fog subdomain-en, aztán majd később eldöntöm, hogy mi legyen. Belső rendszer lesz, szóval bizonyos fokig elő tudom írni, hogy mit használjanak hozzá.
14

JSONP

T.G · 2013. Ápr. 21. (V), 09.31
Ilyenkor jön elő az a kérdés, hogy melyik kezedbe harapjál? :)
Ha nem Ajax hívásokat használsz, hanem az adatokat elposztolod és a szerver a megadott formában válaszol, akkor le tudod ezt szimulálni, de a hátulütők listája hosszabb, nincs PUT, DELETE, nincs speciális header. És ezért fontos az, hogy át tudd írni az url-eket, azaz a CRUD -hoz nem egy, hanem négy különböző url-t is megadhatsz.
ExtJS-ben a JSONP támogatást úgy oldották meg, hogy a proxy-ban csak egy property-t kell beállítani és a technikai megvalósítással nem kell törődnöm, a kód úgy néz ki, mintha Ajax hívás lenne, de közben persze nem az. (gyanítom ez máshol is ugyanúgy el van fedve)
16

Ahm, hát arra most sajnos

inf · 2013. Ápr. 21. (V), 15.25
Ahm, hát arra most sajnos nincs időm, hogy jsonp-vel próbálkozzak emiatt.
13

Még egy kérdés, láttam olyat

inf · 2013. Ápr. 21. (V), 08.29
Még egy kérdés, láttam olyat valamikor, hogy xml fájl-al írták le, hogy a REST service-ben milyen erőforrások vannak. Azt olvastam, hogy a REST önleíró, ha jól tudom, akkor az OPTIONS-re adott válasznak kéne tartalmaznia ezt az xml-t, vagy valami ilyesmi állt össze bennem, de nem találtam semmit róla. Tudsz erről valamit? Elvileg hasonlóan, mint a soap wsdl le lehet írni a json rest service-eket is... Nekem valami ilyesmi hasznos lenne, mert ez alapján tudnék egy proxy-t generáltatni a kliens oldalra...

Saját megoldás már van, az valahogy így néz ki:

{
     "Authorization": {
        "User": {
            "/user": {
                "get": "readAll",
                "post": "create"
            },
            "/user/:id": {
                "get": "read",
                "put": "update",
                "delete": "delete"
            },
...
ezt használja a rest service is a routinghoz, de ha van valami szabvány erre, akkor szívesebben használnám azt...
15

passz. :)

T.G · 2013. Ápr. 21. (V), 09.31
Itt sajnos passzolnom kell, ahol nekem szükségem volt erre, ott sérül az önleírás, a kliens tudta, hogy mit kezdjen az adatokkal. Erre még iránymutatást sem láttam.
17

Okés, köszi, megpróbbálok

inf · 2013. Ápr. 21. (V), 15.26
Okés, köszi, megpróbbálok utánakeresni még egyszer, hátha találok valami használhatót.

Na közben megtaláltam:

<accounts xmlns="urn:org:bank:accounts">
    <account>
        <id>AZA12093</id>
        <link href="http://bank.org/account/AZA12093" rel="self"/>
        <link rel="http://bank.org/rel/transfer edit"
              type="application/vnd.bank.org.transfer+xml"
              href="http://bank.org/transfers"/>
        <link rel="http://bank.org/rel/customer"
              type="application/vnd.bank.org.customer+xml"
              href="http://bank.org/customer/7t676323a"/>
        <balance currency="USD">993.95</balance>
    </account>
    <account>
        <id>ADK31242</id>
        <link href="http://bank.org/account/ADK31242" rel="self"/>
        <link rel="http://bank.org/rel/transfer"
              type="application/vnd.bank.org.customer+xml"
              href="http://bank.org/transfers"/>
        <link rel="http://bank.org/rel/customer"
              type="application/vnd.bank.org.customer+xml"
              href="http://bank.org/customer/7t676323a"/>
        <balance currency="USD">534.62</balance>
    </account>
</accounts>
Úgy látszik ez az önleírás arról szól, hogy az xml-ben az erőforrásra hivatkozó url-t adjuk át id, vagy ilyesmi helyett. Bár elméletileg az options-re is lehet így válaszolni, szerintem az nem elterjedt.

Találtam olyat is, hogy wadl vagy wsdl fájllal írták le a rest service-t, arra is van lehetőség.

Van egy rakat rest service leíró megoldás, de egyik sem tetszik igazán. Általában az átküldött adatok típusával is operálnak, nekem viszont elég lenne egyelőre csak a controller action-öket összekötni az url-ekkel.

Más is ötletelt az OPTIONS-re, úgy látom. Ezek szerint egyáltalán nem elvetélt ötlet options-re tenni a service leírását.
20

Szép lassan közelítek ahhoz,

inf · 2013. Ápr. 22. (H), 01.04
Szép lassan közelítek ahhoz, amit keresek:
http://www.bennadel.com/blog/2419-Mapping-RESTful-Resource-URIs-Onto-URL-Parameters-And-Server-Side-Events.htm

Végülis nekem csak a resource map-et kell leírnom ahhoz, hogy proxy-t tudjak generáltatni. Még a validáláshoz esetleg kellenek majd a típusok.

Valszeg valami ilyesmi lesz a végleges forma a resource mappingemnél:

[
    {
        "module": "Authorization",
        "endpoints": [
            {
                "url": "/user",
                "resource": "User",
                "bindings": [
                    {
                        "method": "GET",
                        "action": "readAll"
                    },
                    {
                        "method": "POST",
                        "action": "create"
                    }
                ]
            },
...
Ha lesz időm, akkor ezt php-s annotációkból fogom generáltatni, amik ugyanúgy fognak kinézni valszeg, mint a java annotációk a JAX-nál vagy a spring-nél. A C#-os annotációk, amiket láttam, nekem túl verbose-ek. Annotációnál szerintem jobb az egyszerűség a config fájlban meg a bőbeszédűség. Annyi extra van az én megoldásommal, hogy egy osztályhoz több url-t is hozzá lehet rendelni. Általában úgy csinálják, hogy egy url-hez egyetlen osztályt rendelnek, annak meg a metódusait megfeleltetik egy-egy http method-nak. Valahogy így:


/**
@endpoint "/access"
*/
class Access
{
    public function get()
    {
    }

    public function post()
    {
    }

    public function put()
    {
    }

    public function delete()
    {
    }
}
Ezzel nálam az nem stimmel, hogy a /access és a /access/:id nagyon sok közös dolgot használ, ezért szerintem jobb, ha egy osztályra mutatnak. Ha erre van valami bevált ötletetek, módszeretek, arra kíváncsi vagyok.

Agyaltam ezen is, és arra jutottam, hogy ami gyűjteményre vonatkozik, azt jobb statikus metódosba tenni, ami meg konkrét bejegyzésre, azt meg sima metódusba. Jelenleg úgy áll a dolog, hogy ezt a lehetőséget nem fogom kihasználni, inkább maradok a sima controller objectnél.

Közben megírtam kliens oldalra, hogy a szervertől elkért json-ból generáljon proxy-t, illetve a kliens oldali url-ekhez a router-t szintén egy json fájlból generáltatom, aztán kattintásra, vagy közvetlen hívásra automatikusan betölti a megfelelő modult, és azon meghívja a megfelelő metódust. Nagy moduloknál lassú nettel és géppel talán lehet valamekkora késés így... Talán később teszek bele külön eseménykezelőt, hogy kirakja a loading feliratot, vagy ilyesmi. A service proxy-ját ennél jóval bonyolultabb automatizálni, mert ott el kell dönteni, hogy a bejövő jsont milyen Model, Collection, Record, stb... osztályba szórom bele. Lehet, hogy jobban járok, ha a proxy nyers adatot küld és fogad, de úgy meg nem használom ki a Backbone.sync nyújtotta kényelmet...
21

Ez esetleg segíthet

MadBence · 2013. Ápr. 22. (H), 16.55
http://css.dzone.com/articles/designing-beautiful-restjson (a #weblabor csiripek között láttam)
23

Köszi, majd ránézek, de

inf · 2013. Ápr. 25. (Cs), 00.12
Köszi, majd ránézek, de előtte befejezem a mostani REST alkalmazást :D