For designing and creating a RESTful API the following question occurs:
The API supports GET (for queries), POST (for creating), PUT (for updates) and DELETE (for deleting).
Lets assume in the database we have an article and a shop both already existing.
Now we need a rest call to link the article instance to the shop instance. Which of the following solutions is the best / most clean REST design:
If there is no clear answer or all solutions are equally good this may also be a valid answer if there is a clear argumentation why.
I presume in this situation you already have a collection of shop
s and a collection of article
s, and you just wish to link two together.
One option is to expose a more db like 'resource' that presents this link, and have operations like
POST /shopArticleLinks HTTP/1.1
{ "shop" : xxx,
"article: YYY
}
I would personally look to expose it as a property of the shops and/or articles in a more natural manor, like
PUT /shop/<ID> HTTP/1.1
{ /* existing details */
"articles": [ /* list of articles */ ]
}
I've used JSON there, but of course use what ever format you want to use. I've also stuck with using PUT as you stated, but keep in mind that with PUT you should send a full replacement for the new modified version, PATCH can be used to send partial updates, but then you need to consider how you want do that, may something like
PATCH /shops/<ID>/articleLinks HTTP/1.1
{ "add" : [],
"remove : []
}
Don't forget that server side you can look at what articles
are being refereed to and ensure they have a proper back pointer.
Additional thoughts
Regarding the second method, where you expose the link as a property of the shop
and/or article
resources. Keep in mind that it is perfectly acceptable (and in this case rather appropriate) that when you update the links in a given shop
that the links in the corresponding articles
are also updated.
/shop/id/article/id/
You cannot use this because at the moment you want to link them, this endpoint doesn't (or at least shouldn't) yet exist. It is the action of linking them together that should define this endpoint.
/shoparticlerelation/
You should not use this because a shoparticlerelation
is not a resource / entity. Usually with rest, every named url segment represents a resource that can be CRUD-ed. /shops
is a good example and so is /articles
but this one isn't.
I suggest the following:
Define the following endpoints
/shops
for POSTing new shops/shops/id
for operating on a single shop/articles
for POSTing new articles/articles/id
for operating on a single article
Then to link them together you can do a so called PATCH request, to update a shop's articles, or an article's shops:
PATCH /shops/1 HTTP/1.1
{
"attribute": "articles",
"operation": "add",
"value": "8" // the article id
}
and
PATCH /articles/9 HTTP/1.1
{
"attribute": "shops",
"operation": "add",
"value": "1" // the shop id
}
Based on your comments I made the assumption that an Article model has a list of Shops as attribute, and vice-versa, making this approach valid.
A PATCH request is used to modify an existing resource by specifying how and what to update. This is different from a PUT because a PUT replaces the entire resource with values from the request, however PATCH is only used to modify (not replace) a resource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With