How to delete list of items with REST API - rest

I'm wondering about deletion of bunch items using REST API. But I can't find right way. I'm implementing this just by POST method. And it seems as deviation from REST nature. Is there some way with DELETE method for deletion of a collection?

I see two ways to do that with REST:
If you want to delete all the elements, you can use the method DELETE on a list resource itself. For example: DELETE /contacts/ will remove all contacts.
If you to delete only a subset, you can leverage the PATCH method and the JSON PATCH format (see http://jsonpatch.com/ and https://www.rfc-editor.org/rfc/rfc6902) to specify which elements to delete. Here is a sample:
PATCH /contacts
[
{ "op": "remove", "path": "/contacts/1" },
{ "op": "remove", "path": "/contacts/2" },
{ "op": "remove", "path": "/contacts/3" }
]
The following could give you some hints: https://templth.wordpress.com/2015/05/14/implementing-bulk-updates-within-restful-services/.
Hope it helps you,
Thierry

Related

Should the resource ID be put in URL of PUT and PATCH requests?

Should PUT's and PATCH's URL contains ID or could it be put inside the body?
PUT /person/UUID {"name": "Jimmy"}
OR
PUT /person/{"UUID":1, "name": "Jimmy"}
( the same for the PATCH)
?
As PUT is defined as Replace the current document found at the URI location with the one provided in the payload sending a PUT request to /person should probably lead to a removal of any person managed by that particular endpoint, in case that URI represents a collection of persons.
As mentioned in this post one might use a URI without some special entity identifier in case this is an all purpose container. Think of a clipboard where you can copy some data to to later on retrieve it to paste it somewhere else. In such a case the identifier is implicitly given by the URI itself, as after all URI stands for unique resource identifier
Note that a URI as a whole identifies a resource and does not necessarily imply some form of parent-child structure. A client especially should not attempt to extract knowledge from an URI at all.
In regards to PATCH it depends. Usually one should use a media-type that is intended for patching such as JSON Patch or JSON Merge Patch.
The former representation defines certain fields that state that a field should be added, removed or replaced with a given value in a notation like the one listed below:
PATCH /my/data HTTP/1.1
Host: example.org
Content-Length: 326
Content-Type: application/json-patch+json
If-Match: "abc123"
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
JSON Merge Patch however works differently. It defines some default rules that instruct a server on how to apply the changes to the target document. A document like below i.e. will either add or update field a to have value z afterwards while the property f of c's object has to be deleted. All the other remaining properties of that resource remain as they are.
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json
{
"a":"z",
"c": {
"f": null
}
}
Both of these media-types could be used to send a request directly to the "collection"-resource as both can target sub-elements by definition. However, in terms of caching I'd try to avoid it.
Caching in HTTP works de facto on the URI of the resource. Any unsafe operation performed on that URI leads to the cache invalidating a stored representation for that target. I.e. if you previously invoked GET /person/1 and now perform a PUT or PATCH, which both are unsafe operations, on /person the data might get updated, though a client requesting GET /person/1 afterwards may still retrieve the cached response via the cache as it is unaware of any changes done to that resource.

How to choose an approach for updating resources in REST

I am considering two approaches when updating rest api and i am not sure how to choose which approach to follow
For example
GET /service/1000
{
"service_id": 1000,
"name": "Some service"
"status": "ACTIVE"
}
Now If I want to update this service I could do
PUT /service/1000
{
"service_id": 1000,
"name": "Some service"
"status": "INACTIVE"
}
or
POST /service/1000/update-status
{
"status": "INACTIVE"
}
or even
POST /service/1000/activate
{
}
and
POST /service/1000/deactivate
{
}
So my question is what is the rule of thumb to follow when choosing approach how to update REST?
EDIT
This question is not about when to use POST/PATCH/PUT, it is about should resource be update calling the same resource, or should it be updated using an action. For example, twitter uses actions https://developer.twitter.com/en/docs/api-reference-index
From what you are considering put is more appropriate however I in some cases patch is more appropriate so when you are changing the value of resources you consider using patch but when you are adding a new property put is more appropriate see---
REST API PATCH or PUT

API examples using JSON PATCH for partial updates

I'm looking for the best solution to apply a partial update to an object with a REST API (ASP.NET)
I originally wanted to use "JSON Merge Patch" format (rfc7396), but I was not able to do it with ASP.NET (hard to differentiate ignored fields, and fields set to null)
I tried to use PATCH with JSON PATCH format and it is working.
Ex. :
[
{ "op": "replace", "path": "/Name", "value": "patchedValue" },
{ "op": "replace", "path": "/EnumTest", "value": "blo" },
{ "op": "replace", "path": "/SubItem/Name", "value": "patchedValue" }
]
I see that Microsoft support this format (asp.net core json patch), but I have no idea if this format is often used. I don't want to be the only one using it... I'm looking for API from big companies that is using this format for partial update. Do you have some examples ?

Areapath is not correct in programmatically generated TFS/VSTS workitem

I am trying to create workitem in TFS/VSTS with custom area-path
for example I want to be my workitem areapath to be "cde"
Area-paths in my project are similar to below
My patch element for area-path is as below.
{
"op": "add",
"path": "/fields/System.AreaPath",
"value": "VSTS_TFS_Test\abc\cde"
}
I am using batch create method for this hence REST call url is as below
<<my tfs collection url>>/_apis/wit/$batch?api-version=1.0
However this always just display project file (VSTS_TFS_Test) as area in work item. Please refer below screen.
I wanted to "cde" to be area in work item. Please provide some guidence to make this possible
references :
https://www.visualstudio.com/en-us/docs/integrate/api/wit/work-items
The problem should be your patch element.
Just try below patch element:
{
"op": "add",
"path": "/fields/System.AreaPath",
"value": "VSTS_TFS_Test\\abc\\cde"
}
After the patch, just refresh your browser to check the work item again.

REST PATCH for all resources of a given type

I have a set of resources in a REST API, lets say it something like this:
GET /folders
[{ "id": "x", "watched": true }, { "id": "y", "watched": true }, ...]
I've implemented "stop watching" command as a PATCH:
PATCH /folders/x { "watched": false }
What is the right way to implement "stop watching all folders"?
I thought of
PATCH /folders { "watched": false }
But I am not sure if this makes sense (the collection itself does not have a watched property).
Or is it something that shouldn't be implemented on API level at all (and instead iterated by client)?
That would seem inefficient though.
I think PATCH /folders { "watched": false } is completely appropriate. Let the implementation decide how the folders will be patched with the given representation of the intended resource state (your JSON). There are no constraints about how the resource representations should look like, they should be self descriptive, so in this case they should have a standard content-type, that's all. (GET responses can be different.)
I don't recommend you to iterate over the collection by your client, since it is not atomic, it can lose connection at any time. You should send only a single request about this.