Page 1 of 2 1 2 LastLast
Results 1 to 15 of 18

Thread: Rest

  1. #1

    Rest

    Hallo hallo,

    Ben momenteel een REST API aan het ontwerpen/maken en zit met de volgende vragen. Stel ik heb de volgende URI's:
    Code:
    POST /klanten/1/orders
    Volgens de API design guidelines van Microsoft is betekent dit dat je een order aanmaakt voor customer 1.

    Is het gebruikelijk om in dit geval orders voor klanten op deze manier te maken en wat zijn de voordelen? Ik vind het namelijk erg onlogisch. Het lijkt mij veel netter om het zo te doen.
    Code:
    POST /orders
    Bij de eerste methode kun je in sommige gevallen volgens mij redelijk wat verschillende URI's krijgen die naar hetzelfde doen en dat lijkt mij onwenselijk, maar misschien vergis ik mij hierin.

    Bij een GET zie ik er wel de voordelen van in omdat je dan niet een aparte zoek query hoeft mee te geven als parameter, maar ook daar valt wat op af te dingen naar mijn mening.

    Wat is wijsheid?

  2. #2
    Het is nogal subjectief, en zelfs in de guidelines waar je naar linkt, staat dat het al snel onoverzichtelijk wordt, wanneer je bijvoorbeeld moet posten naar /klanten/1/orders/20/producten om een product toe te voegen aan order 20.

    Ik heb zelf een cursus gedaan bij Jim Webber, co-auteur van o.a. Rest in practice, en die gruwelde van dit soort urls. Het is volgens hem vooral makkelijk omdat je op die manier met de hand kan uitzoeken hoe een API gestructureerd is, en gebruik/misbruik kan maken van diverse frameworks die automatisch op dit soort samengestelde urls kunnen inhaken. Zijn mening is dat je maar een paar ingangen zou moeten hebben naar je API, bijvoorbeeld voor het maken opvragen van customers. De url om de orders van een klant op te halen zou je kunnen krijgen door hypermedia links terug te geven in je klant response (HATEOAS, ook beschreven in de Microsoft standards). Als je dat goed doet, dan kan je met 1 of enkele ingangen je hele API ontdekken, en zou de url van een order in principe een willekeurige string kunnen zijn. Op die manier zou je veel flexibeler zijn in het herstructureren van je API, en loop je niet de kans dat mensen (valse or ongewenste) aannames gaan doen over de structuur van je API urls.
    Je kan zelf content types verzinnen om duidelijk te maken wat iets nou eigenlijk is. Je kan bijvoorbeeld GET /e4f4c987-bf83-4bee-b92d-49f7bef2d0a5 doen en als accept-type application/vnd.order.v1+json om aan te geven dat je een order terug wilt hebben. Je server kan dan netjes antwoorden of de resource niet bestaat, of dat hij wel bestaat maar een ander type heeft.

    Maar goed, de waarheid ligt misschien in het midden. Als je niet helemaal overboord gaat met wat ik in die alinea hierboven schrijf, dan zou ik in ieder geval het gevoel volgen dat diep geneste urls als /klanten/1/orders/20/producten hun doel voorbij schieten. Ik denk dat het op zich geen kwaad kan om een order voor klant 1 te maken door te posten naar klanten/1/orders, maar zodra je die order en z'n id hebt, zou ik die opvragen en aanpassen door GET's en PUT's uit te voeren op /orders/20. Of gewoon posten naar /orders en het klantid meegeven in de body.
    Last edited by GolezTrol; 04-Mar-19 at 00:06.
    1+1=b

  3. #3
    Dank je wel voor je antwoord. Ik denk dat ik het gewoon heel simpel ga houden en niet meerdere url's maak die hetzelfde doen. Dat lijkt me het meest overzichtelijk. Ik begon alleen te twijfelen nadat ik wat van die geneste urls had gezien. Ik vroeg me af of het ook voordelen had, want ik zag ze niet echt.

    Wat ik ook verwarrend vind is dat je bij

    Code:
    /klanten/1/orders/
    verwacht dat er een nieuwe order wordt aangemaakt, maar dat er bij
    Code:
    /klanten/1/orders/20/producten
    een bestaand product wordt toegevoegd aan de order en niet dat er een nieuw product wordt aangemaakt. Met andere woorden je zou verwachten dat er slechts een record in een order_product tabel wordt toegevoegd.

    Wat ik merk bij het ontwerpen van REST services is dat het heel verleidelijk is om er functionaliteit in te bouwen die waarschijnlijk gewoon op de client thuis hoort. Die lange geneste url's zijn daar een voorbeeld van. Voorheen gebruikte ik ook envelops in mijn responses, maar daar ben ik om dezelfde reden vanaf gestapt. Ook over HATEOAS heb ik zo mijn twijfels.

  4. #4
    Quote Originally Posted by luigi View Post
    ...maar dat er bij /klanten/1/orders/20/producten een bestaand product wordt toegevoegd aan de order en niet dat er een nieuw product wordt aangemaakt.
    Lijkt mij eigenlijk wel logisch. /klanten/1/orders/20/producten zijn geen producten maar "productregels". Dus items van een order. Met /klanten/1/orders/20/producten maak je dus zo'n orderregel aan. Heel logisch

    Als je /orders gaat gebruiken zou je eigenlijk ook /orders/producten moeten gebruiken om die orderregels toe te voegen. Of ga je dat via JSON o.i.d. doen? Dan kun je ook net zo goed een /api maken en daar via JSON alles meegeven. Of het nu nieuwe klanten, orders of wat dan ook zijn.

  5. #5
    Persoonlijk zou ik de url opbouw voor de REST modulair en simpel insteken. Dus op /klanten doen je alles met klanten zoals aanmaken, wijzigen, verwijderen en opvragen. Voor /orders doe je precies hetzelfde. (/orders valt niet onder /klanten) Wanneer je een order wilt koppelen aan een klant dan zou ik een JSON meesturen waarin dit specifiek bepaald is. Deze JSON stuur je mee wanneer een order wordt aangemaakt. (Je kunt ook gewoon parameters in een request gebruiken i.p.v. json) De methode die je nu toepast lijkt nu logisch maar wanneer je veel modules hebt dan kan het een wirwar worden.

    Edit: Bij nader indien kan ik toch vinden de methode die jullie hierboven schetsen. Een goede documentatie van de API is cruciaal om geen dubbele en onlogische constructies te krijgen.
    Last edited by PiSymbol; 04-Mar-19 at 14:14. Reason: Typo
    Onmogelijk... Is geen feit, maar een mening.

  6. #6
    Code:
    /klanten/1/orders/20/producten
    Wat ik niet begrijp is dat waarom je i.p.v. 20 in de url te zetten dit niet gewoon in je JSON body meegeeft bij een post. Wat is hier de gedachte achter?

    Het enige voordeel dat ik kan ontdekken aan bovenstaande url is dat je wat makkelijker inzicht krijgt in de structuur.

  7. #7
    Allereerst zijn er geen regels voor een API. Zolang er logica is en de API gedocumenteerd is, heb je vrijheid. De reden waarom identifiers meegegeven worden in de url is gemak en inderdaad leesbaarheid. In een JSON bestand worden normaliter details meegezonden of data wat niet in de url past.
    Onmogelijk... Is geen feit, maar een mening.

  8. #8
    Denk dat ik maar van deze vrijheid gebruik ga maken

  9. #9
    ik zou vooral ook eens wat api's bestuderen in het zelfde probleemdomein als waar jouw applicatie moet werken.

    Zelf ben ik voorstander van eenvoudige url's, waarbij je een json meestuurt met de relevante data.

    Probleem met rest is een beetje dat er nog niet echt regels voor zijn. Meestal zie je implementaties met het standaardwerk, post, put, get en delete. Soms kom je ook api's tegen die patch gebruiken, alleen zie je daar dan ook weer discussies over hoe je patch zou moeten toepassen.

    Belangrijkste aan een api is denk ik dat de logica begrijpelijk is voor de gemiddelde programmeur. Verder zou ik adviseren om hem zeker te documenteren in openapi.

  10. #10
    Zelf ben ik voorstander van eenvoudige url's, waarbij je een json meestuurt met de relevante data.
    Ja dat ben ik ook. Zeker in combinatie met de kbmmw smartservices. Als het even kan ik wil ik dezelfde methodes gebruiken voor REST en voor kbmmw clients. Maar ik zie redelijk wat voorbeelden ook op fora zoals stackoverflow, die een paar niveau's diep gaan. Ik heb tot nu toe nog niet echt een reden gelezen waarom dit beter zou zijn dan de waardes gewoon in JSON mee te sturen ipv in de URL.


    Belangrijkste aan een api is denk ik dat de logica begrijpelijk is voor de gemiddelde programmeur. Verder zou ik adviseren om hem zeker te documenteren in openapi.
    Zag dat kbmmw nu ook een soort API documentatie tool of iets dergelijks heeft. In beginsel is de API alleen voor mij om eventueel een webapplicatie aan mijn server te hangen, maar documentatie kan nooit kwaad.

  11. #11
    Zag dat kbmmw nu ook een soort API documentatie tool of iets dergelijks heeft.
    Kim werkt aan een stub framework. Een van de eerste resultaten daarvan is nu dat je openapi documentatie kunt genereren van je api die je gemaakt hebt met smartservices.

    Openapi is min of meer de defacto standaard aan het worden voor het documenteren / vastleggen van je rest api.

  12. #12
    Quote Originally Posted by luigi View Post
    Ja dat ben ik ook. Zeker in combinatie met de kbmmw smartservices. Als het even kan ik wil ik dezelfde methodes gebruiken voor REST en voor kbmmw clients. Maar ik zie redelijk wat voorbeelden ook op fora zoals stackoverflow, die een paar niveau's diep gaan. Ik heb tot nu toe nog niet echt een reden gelezen waarom dit beter zou zijn dan de waardes gewoon in JSON mee te sturen ipv in de URL.



    Zag dat kbmmw nu ook een soort API documentatie tool of iets dergelijks heeft. In beginsel is de API alleen voor mij om eventueel een webapplicatie aan mijn server te hangen, maar documentatie kan nooit kwaad.
    Its a matter of taste which method to choose.
    But the rules of thumb are:
    - If you want an easy way for people to access your API from a regular browser, then predominately use the URL based arguments, since they can be typed anywhere
    - Generally do not include free text style data in an URL. If that is needed, provide the data as JSON

    Hence if adhering to the above "rules", you would generally do this:

    - Use GET and URL with ID (numeric or compact GUID or similar) for accessing data. Return JSON or pure text/plain.
    - Use DELETE and URL with ID (as above). Return status as JSON or pure text/plain.

    Creating data can be done using either PUT or POST. There are RFC's saying to use PUT to create/fully replace (x:=10) and POST for update/modify. Eg. x:=10 vs inc(x). The later would be considered a POST case.
    However there are also arguments going on for not using PUT at all and only using POST. Its a war of religion. However official RFC is supposed to be interpreted as:
    Some prefer using PATCH for updating/adding incremental information to existing data. Again its debatable if not simply to use POST also in those cases.

    - Use PUT with no ID in URL and JSON for submitting new data
    - Use PUT with ID (as above) in URL and JSON for updating existing data
    - Use POST with ID and data in JSON for updating existing data

    And then comes KISS into mind... I prefer making the API as simple for end users as possible.
    Hence I would primarily use GET, DELETE and POST and put simple ID's in URL for GET and DELETE.

  13. #13
    SillyMember
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,725
    Quote Originally Posted by PiSymbol View Post
    Allereerst zijn er geen regels voor een API. Zolang er logica is en de API gedocumenteerd is, heb je vrijheid. De reden waarom identifiers meegegeven worden in de url is gemak en inderdaad leesbaarheid.
    Dat klopt niet voor REST waar de URI gebruikt wordt om een resource te adresseren en die identifier dus onderdeel moet zijn van de URI.
    All methodologies are based on fear. -- Kent Beck.

  14. #14
    SillyMember
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,725
    Quote Originally Posted by Kim Bo Madsen View Post
    Its a matter of taste which method to choose.
    Creating data can be done using either PUT or POST. There are RFC's saying to use PUT to create/fully replace (x:=10) and POST for update/modify. Eg. x:=10 vs inc(x). The later would be considered a POST case.
    I think it is the other way around for REST.
    POST is used on a collection resources to add a child resource. => Create
    PUT is used on a indiviual resource to update. => Update
    All methodologies are based on fear. -- Kent Beck.

  15. #15
    SillyMember
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,725
    Om een orderregel (hier product) toe te voegen (mocht dat kunnen) gebruik ik:
    POST api/orders/20/producten (met een nieuwe productregel in json of xml als POST data)
    All methodologies are based on fear. -- Kent Beck.

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •