Hulp gevraagd bij opzetten RESTful web service

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Rjn87
  • Registratie: Maart 2006
  • Laatst online: 13-01 22:10
Beste Tweakers,

Momenteel ben ik bezig met het opzetten van een RESTful webservice met ASP.NET Web API. Het wordt een webservice die gebruikt gaat worden voor de communicatie tussen een bestaande ERP-applicatie en een nieuw te bouwen mobiele boodschappenlijst app.

Ik wil de webservice restful opzetten, alleen vind ik het soms nog wel lastig te begrijpen wanneer iets wel of juist niet restful is.

Zo wil ik een boodschappenlijst ophalen op basis van een username:

Ophalen boodschappenlijst
GET
/api/shoppinglists/{username}

En wil ik producten zoeken op basis van een trefwoord of op basis van een streepjescode:

Zoeken product op zoekterm of streepjescode
GET
/api/products/keyword/{keyword}

GET
/api/products/barcode/{barcode}

Volgens mij is dit niet de juiste manier als je een webservice restful wilt opzetten omdat ik op deze manier niet alleen een resource aanduid, maar ook een soort action mee geef.

Zou iemand mij kunnen vertellen hoe je de gegeven voorbeelden omzet in een restful manier?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Er is geen (dé) "RESTful manier"; REST is een term die min-of-meer naar een bepaald principe verwijst en daar houdt het een heel eind op. Ik zie eigenlijk niet echt direct een probleem in wat je wil, maar misschien dat anderen daar anders over denken :)
The REST architectural style describes the following six constraints applied to the architecture, while leaving the implementation of the individual components free to design
...

[ Voor 40% gewijzigd door RobIII op 18-04-2012 16:47 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 12-09 16:28
Wellicht niet het antwoord wat je zocht, maar je zou eens naar deze pdf kunnen kijken welke ik toevallig gisteren tegen kwam: http://info.apigee.com/Portals/62317/docs/web%20api.pdf

Wat bij REST heel belangrijk is, is de relatie tussen verschillende resources (entiteiten, collecties & services). Zo kan ik me voorstellen dat je in de toekomst meer eigenschappen voor een user krijgt dan alleen een shoppinglist.
Dan kan je bijvoorbeeld ook url's gebruiken als:
/api/user/{username} en /api/user/{username}/shoppinglists

Mocht een user dan bijv. ook een naam hebben kan je die relaties aanduiden met bijv:
<user>
<name>voor & achternaam</name>
<shoppinglists href="/api/user/someUsername/shoppinglists" />
</user>

Een shoppinglist kan er dan bijv. als volgt uit zien:
<shoppinglist>
<user href="/api/user/{username}" />
<product href="/api/product/1234" />
<product href="/api/product/654" />
<product href="/api/product/9182" />
</shoppinglist>
Zoeken product op zoekterm of streepjescode
GET
/api/products/keyword/{keyword}

GET
/api/products/barcode/{barcode}
Je kan je afvragen of een keyword nu wel een (verzameling van) resource(s) is. Als dat niet het geval is (en ik denk dat dat niet het geval is), dan zou dat eigenlijk niet in de url zelf moeten zitten.
Wat je bijv. wel kan doen is iets als /api/products?q=barcode:{barcode}

Met REST is de URL de identifier van je resource. In principe zou iedere resource ook maar gerepresenteerd moeten worden door 1 url (immers, hoe kan je meerdere id's hebben per resource?). Door ?q= te gebruiken blijft het deel voor de query string intact, en zorg je er dus voor dat iedere resource slechts 1 url heeft (voor het gemak tel ik de query string nietmee als onderdeel van de url in deze context).

Waar je op een gegeven moment tegen aan gaat lopen is dat een query string een maximale lengte heeft. Welke dit precies is kan verschillen per proxy en webserver, maar ergens zit een max. Op dat moment kan je beter je zoekopdracht in de request body opgeven. Echter, een request body opgeven bij een GET request kan in ongedefinieerd gedrag resulteren (volgens rfc2616 hoeven request bodies bijv. niet gecached te worden). POST'en naar een collectie is ook geen optie, want dan voeg je een entry toe in plaats van te zoeken.
Gelukkig _mag_ je binnen REST ook services toepassen (om Roy Fielding te parafraseren "A resource is something of which you can say what it is, not what it does"). Hier moet je wel voorzichtig mee zijn, en zou uitzondering moeten zijn, om te voorkomen dat je alsnog een xml-rpc service gaat bouwen. Omdat het bij REST wel om pragmatisme gaat gebruik ik hier standaard een search service voor. Stel dan dat je uitgebreid wil zoeken op products, dan zou je kunnen POSTen naar /api/products/search en daarbij in bijv. een xml document je zoekparameters definieren. Vervolgens kan een dergelijke service een document serveren als:
<products>
<product href="/api/product/123">
</products>

Wat je ook zou kunnen doen is deze zoekopdracht in je api opslaan. Om na het aanroepen van de search service te redirecten met een 302 of een 303 status code, afhankelijk van of je deze zoekopdracht wil persisteren. De url waar je dan naar redirect is dan bijv. /api/products?searchId=123981
Let hierbij wel op dat je niet iets als sessies (of .net's counterpart) kan gebruiken, daar REST api's stateless zouden moeten zijn.

Al met al REST FTW. maar het kost wel wat tijd om er 'behendig' in te worden ;) Er is overigens ook een api-craft mailinglist waar heel veel zinnige resources te vinden zijn.

Mocht je het verder interessant vinden zou je ook eens kunnen zoeken op termen als ETags & HATEOAS. En verder iedere avond voor het naar bed gaan RFC 2616 uit je hoofd leren, 's ochtends Roy Fieldings thesis uit je hoofd leren. En deze twee documenten ook als bookmark instellen >:)

Oh, en als je bezig gaat met het wijzigen van resources, bekijk dan ook even RFC5789, en vraag je af of je niet beter PATCH kan gebruiken dan PUT (wat volgens mij nog 'de standaard' is binnen .NET REST omgevingen).

offtopic:
Zoals hierboven al gemeld is REST geen harde set regels. Wat in deze post staat zijn wat beginselen en best-practices zoals ik ze ervaar als ik een RESTful api maak (wat meer dan de helft van mijn werk inhoudt). Het kan goed zijn dat anderen hier een andere mening over hebben... =)

[ Voor 8% gewijzigd door Freeaqingme op 18-04-2012 19:45 ]

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • Rjn87
  • Registratie: Maart 2006
  • Laatst online: 13-01 22:10
Dit was exact het antwoord waar ik naar opzoek was :).

Het is me nu wel een stuk duidelijker. Heb nog één vraag.

Als je een zoek service gebruikt zoals jij beschrijft. Post je dus je zoek parameters in een xml document (kan ook een json object lijkt mij?) naar de webservice. Vervolgens maakt de webservice een lijst met alle overeenkomende producten. Deze wordt terug gestuurd richting de app en vervolgens haalt deze alle producten in de boodschappenlijst op via een GET. Begrijp ik het zo goed?

Hartelijk dank voor de uitgebreide en duidelijke uitleg! :)

Edit: Heel goed document trouwens. Haal er veel nuttige informatie uit.

[ Voor 6% gewijzigd door Rjn87 op 19-04-2012 09:40 ]


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 12-09 16:28
Rjn87 schreef op donderdag 19 april 2012 @ 09:11:
Als je een zoek service gebruikt zoals jij beschrijft. Post je dus je zoek parameters in een xml document (kan ook een json object lijkt mij?) naar de webservice. Vervolgens maakt de webservice een lijst met alle overeenkomende producten. Deze wordt terug gestuurd richting de app en vervolgens haalt deze alle producten in de boodschappenlijst op via een GET. Begrijp ik het zo goed?
Yup, dat kan met json, en kan heel goed the way to go zijn.

Waar je wel tegen aan gaat lopen is dat je misschien een keer alle zoekresultaten meteen wil weergeven. Als dat er dan 25 zijn moet je - terwijl de bezoeker wacht - 25 url's gaan opvragen (voor ieder product 1). Voor nu zou ik dat op de koop toe nemen.

In de toekomst zou je kunnen kijken naar hoe bijv. google partial responses gebruikt. Als je dan bijv. een query string parameter mee kunnen geven: ?scope=product(name,href)

Dan zou de response kunnen zijn:
<products>
<product href="/ilnknaarproduct/123">
<name>foobar</name>
</product>
</products>

In plaats van:
<products>
<product href="/linknaarproduct/123" />
</products>

Edit:

Natuurlijk kan bovenstaande ook in een json equivalent. Toevallig ben ik fan van xml. Dit omdat ik geen javascript gebruik en fan ben van xpath. Daarnaast kan je met xml heel mooi XSD's opstellen en aan de hand darvan al je input valideren.

[ Voor 9% gewijzigd door Freeaqingme op 19-04-2012 18:07 ]

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

Freeaqingme schreef op donderdag 19 april 2012 @ 17:00:

Daarnaast kan je met xml heel mooi XSD's opstellen en aan de hand darvan al je input valideren.
Je kunt JSON ook handig valideren dmv JSON-schema's.

Aunt bunny is coming to get me!


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 12-09 16:28
iH8 schreef op donderdag 19 april 2012 @ 21:06:
[...]


Je kunt JSON ook handig valideren dmv JSON-schema's.
Hey, da's handig! Als json nu ook attributen zou krijgen en human readable zou zijn dan was het 't helemaal mooi :D

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

Freeaqingme schreef op donderdag 19 april 2012 @ 21:08:

Hey, da's handig! Als json nu ook attributen zou krijgen en human readable zou zijn dan was het 't helemaal mooi :D
Zend_Json::prettyPrint(); ? ;) :D

hier ook nog maar in de twitter-repeat dan: Dojo heeft momenteel al een werkende implementatie van JSON-schema zie: http://www.sitepen.com/blog/2008/10/31/json-schema/

Aunt bunny is coming to get me!


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Freeaqingme schreef op donderdag 19 april 2012 @ 21:08:
[...]

Hey, da's handig! Als json nu ook attributen zou krijgen en human readable zou zijn dan was het 't helemaal mooi :D
JSON is alleen maar attributen en is human-readable, hoe bedoel je? ;)

JavaScript:
1
2
3
4
5
6
{
  person: {
    name: 'henk', // attribuut!
    idiot: true   // human readable!
  }
}

Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 29-07 12:04

Kajel

Development in Style

YopY schreef op donderdag 19 april 2012 @ 23:18:
[...]
JavaScript:
1
2
3
4
5
6
{
  person: {
    name: 'henk', // attribuut!
    idiot: true   // human readable!
  }
}
Like.

Acties:
  • 0 Henk 'm!

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 07-09 09:59
Wij volgen min of meer de richtlijnen uit volgend document als er REST services gebouwd worden:
http://info.apigee.com/Portals/62317/docs/web%20api.pdf

er bestaat ook een video filmpje met wat meer uitleg bij het document..

"Live as if you were to die tomorrow. Learn as if you were to live forever"


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 12-09 16:28
Cuball schreef op vrijdag 11 mei 2012 @ 15:25:
Wij volgen min of meer de richtlijnen uit volgend document als er REST services gebouwd worden:
http://info.apigee.com/Portals/62317/docs/web%20api.pdf
Freeaqingme schreef op woensdag 18 april 2012 @ 17:17:
Wellicht niet het antwoord wat je zocht, maar je zou eens naar deze pdf kunnen kijken welke ik toevallig gisteren tegen kwam: http://info.apigee.com/Portals/62317/docs/web%20api.pdf
:)

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 12-09 13:36
Cuball schreef op vrijdag 11 mei 2012 @ 15:25:
Wij volgen min of meer de richtlijnen uit volgend document als er REST services gebouwd worden:
http://info.apigee.com/Portals/62317/docs/web%20api.pdf

er bestaat ook een video filmpje met wat meer uitleg bij het document..
Dit is een scherpe documentatie inderdaad. Het is van een commerciële partij maar desondanks erg sterkt en gefocussed op standaarden van grote partijen. Die bepalen uiteindelijk de standaarden.

Dit is eigenlijk een onmisbaar artikel van de bedenker van REST:

http://roy.gbiv.com/untan...-must-be-hypertext-driven

Met name dit stukje:
A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API).
Het zou in basis voldoende moeten zijn als je de start url van de API weet. Van daaruit kan je links maken naar vervolgstappen waardoor je meteen kan verkennen welke resources beschikbaar zijn. Mijns inziens zie je dat nog veel te weinig in de praktijk terwijl het veel tijd kan schelen als je met een API aan de slag gaat.

Ondanks dat het topic van begin mei is toch relevant denk ik.
Pagina: 1