Resources voor n-to-n relaties

In de API-strategie v1, API-09 voor 1-to-n relaties geeft heel duidelijk aan “[…] De afhankelijke resource heeft geen eigen eindpunt.” Dit lijkt me logisch.

Voor n-to-n relaties wordt het volgende voorbeeld gegeven en er wordt vermeld dat deze 2 endpoints hetzelfde resultaat opleveren:

GET /aanvragen/12/activiteiten
GET /activiteiten?aanvraag=12

Op zich helder.

Vraag 1 Er wordt echter niet expliciet vermeld dat n-to-n relaties altijd een eigen “tussentabel” resource moeten hebben (in dit voorbeeld: /activiteiten. Is dit de bedoeling of is dit niet verplicht?

Vraag 2 Moet de omgekeerde relatie ook aanwezig zijn als resource (en niet alleen middels filtering), dus:

GET /activiteiten/67/aanvragen/

Vraag 3 Hoe zit het verder met n-to-n relaties die verder genest zitten. Bijvoorbeeld eigenschappen die door meerdere activiteiten gebruikt kunnen worden:

GET /aanvragen/12/activiteiten/34/eigenschappen/

Komt er dan weer een “tussentabel” resource op root niveau /eigenschappen? Of wordt dat anders opgelost?

@dvh Zou jij hier een antwoord op willen geven?

Hoi @Joeri ,

Excuses voor de late reactie. Vooropgesteld: de API Strategie is een guideline. De exacte invulling moet je voor je eigen usecase het beste inschatten, zolang er maar geen compleet nieuwe dingen verzonnen worden. Los van dat hieronder mijn feedback:

  1. Mocht je een overzicht van álle activiteiten willen hebben dan is /activiteiten een logisch vertrekpunt. Als je die dan toch al hebt dan lijkt me de stap naar /activiteiten?aanvraag=12 redelijk eenvoudig en kun je je afvragen wat de meerwaarde is van /aanvragen/12/activiteiten. Heb je deze laatste reeds geïmplementeerd en heb je totaal geen usecase voor een /activiteiten collectie dan zou ik deze voorlopig mooi achterwege laten.

  2. Hiervoor geldt hetzelfde. Als je er linksom of rechtsom maar bij kunt komen (linksom en rechtsom zijn dus wel de twee smaken zoals beschreven).

  3. Dat kan, maar ik zou zelf niet oneindig blijven nesten. /aanvragen/12/activiteiten/34 impliceert dat de URI van de activiteit 34 resource afhankelijk is van aanvraag 12. Dat is geen ramp, maar als een activiteit echt een eigen resource is waar er meerdere van zijn zou ik in dit geval minstens een /activiteiten/34 resource op root niveau verwachten. De bijbehorende eigenschappen zou je wellicht kunnen embedden in de activiteit zelf, of als subcollectie onder /activiteiten/34 kunnen hangen.

Voor alle bovenstaande punten geldt overigens dat een juiste HAL implementatie ervoor zorgt dat de URI helemaal niet zoveel uitmaakt. Door het volgen van de waardes van de HAL links kom ik toch wel op de juiste informatie uit, of je nu voor smaakje 1 of 2 kiest.

Kun je hier iets mee? :slight_smile:

Dag @dvh

Wederom bedankt voor je antwoorden!

Aangezien er een passage aan gewijd was in de API strategie vroeg ik me gewoon af of er bepaalde voorkeuren waren met betrekking tot welke resources beschikbaar “moeten” zijn en waar deze dienen te leven. Hoe meer van deze overwegingen worden benoemd in de API strategie, hoe minder vragen er komen van ontwikkelaars, toch?

Dat je het bestempeld als guideline kan ik me prima in vinden. Enige flexibiliteit en pragmatische oplossingen passen prima bij een REST-API. Je HAL-argument onderaan is natuurlijk helemaal waar.

De voorkeur die je uitspreekt “maar ik zou zelf niet oneindig blijven nesten” is een discussie die ik bij ons ook vaak heb. Moet je nesten, hoe diep, en wanneer nest je niet? Wellicht moet deze overweging ook in het document, zonder harde eisen op te leggen.

1 like

Mijn persoonlijke smaak is om maar max 1 subcollectie diep te gaan. Als de resources van die subcollectie dusdanig van aard zijn dat ze ook een eigen ‘detail pagina’ verdienen is het meestal ook logisch deze een eigen root collectie te geven.

Bijv:

  • /auteurs overzicht alle auteurs
  • /auteurs/3 detail informatie auteur 3
  • /auteurs/3/boeken boeken van auteur 3

Je wil van een boek waarschijnlijk ook meer info/enkel de info van dat boek dus zou het boek ook een eigen endpoint moeten hebben:

  • /auteurs/3/boeken/2 detail informatie van boek 2

Maar omdat het vrij logisch is dat je ook een overzicht van álle boeken etc. wil hebben zou ik gaan voor:

  • /boeken overzicht van alle boeken
  • /boeken/2 detail informatie van boek 2
  • /auteurs overzicht van alle auteurs
  • /auteurs/3 detail informatie van auteur 3

Met in /boeken/2 een verwijziging naar /auteurs/3 als de betreffende auteur en in /auteurs/3 een verwijzing naar /boeken?auteur=3 om alle boeken van die auteur terug te vinden.

Ik zou eigenlijk enkel nesten als het om een 1:n relatie gaat waarvan de subresources zelf niet waardevol genoeg zijn om a) een eigen detail info endpoint te hebben en b) een eigen hoofdcollectie te hebben.