Home > Mobile >  How to write delete REST API that accepts a long list of items to delete?
How to write delete REST API that accepts a long list of items to delete?

Time:12-19

I'm writing RESTful APIs and am getting used to the recommended protocols for using HTTP verbs for different operations.

However, I'm not sure how those protocols handle the case where you are deleting a potentially long list of items.

It appears that, like GET, the DELETE verb has no body and so is limited to the length of a URL. So how could you support accepting an arbitrarily long list of items to be deleted?

CodePudding user response:

From the top....

HTTP is our standard for self-descriptive messages, which is subject to the uniform interface constraint. That in turn means that everyone on the web understands HTTP requests the same way.

In other words

DELETE /api/users/5b45eda8-067c-42c1-ae1b-e0f82ad736d6

has the same meaning as

DELETE /www/home.html

In both cases, we're asking the server to enact a change to its resource model.

Because everyone understands these requests the same way, we can create general purpose components (ex: caches) that understand the meaning of messages in the transfer of documents over a network domain and can therefore do intelligent things (like invalidating previously cached responses).

And we can do this even though the general purpose components know nothing about the semantics of the resource, and nothing about the underlying domain model hidden behind the resource.

DELETE, in HTTP, always specifies a single target URI; "bulk delete" is not an option here.

(I haven't found any registered HTTP methods that describe a bulk delete to general purpose components. It's possible that one of the WebDAV methods could express those semantics, but the WebDAV standard also has a lot of other baggage - I wouldn't try repurposing those methods for a "normal" API.)

So if you are trying to DELETE three resources in your API, then you are going to need three requests to do it -- just like you would if you were trying to DELETE three pages on your web site.


That said, if deleting a bunch of resources on your web site using a single HTTP request is more important than letting general purpose components understand what is going on: you have the option of using POST

POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding, 2009

General purpose components will understand that the resource identified by the target URI is changing in some way, but it won't understand what is happening in the payload.

In theory, you could standardize a payload that means "we're deleting all of these resources", and then general purpose components could be implemented to recognize that standard. In practice, good luck.


Now, if instead what you want is a bulk delete of entities in your domain model, you have some options available.

On the web, we would normally use something like a form - perhaps with a check box for each entity. You select the entities that you want to delete, submit the form, and the HTTP request handler parses the message, then forwards the information to your domain model.

You could achieve something similar with a remote authoring idiom - here's a resource whose representation is a list of entities. You PUT to the server a copy of that document with entities removed, and then on the server you make changes to the domain model to match.

It's a very declarative approach: "change the domain model so that the representation of the resource will look like this".

This is analogous to how you would use HTTP to fix a spelling error in a web page: send a PUT request with the new HTML (including the spelling correction) in the request body.

PATCH is very much the same idea: we describe changes to the representation of the resource, and the server passes that information to the domain model. The difference here being that instead of sending the entire representation, we just send a patch document that describes the correction.

If you want an imperative approach - just use POST

POST /Bob
Content-Type: text/plain

Bob,
Please delete domain entities 1, 2, 5, 7

General purpose components won't understand how you are trying to modify the target resource, but they'll at least know that much.


Where things get messy is when there are lots of resources whose representation depends on the same resources. The standards don't offer us much in the way of affordances to announce "here are all the resources that have changed".

Cache invalidation is one of the two hard problems. HTTP has some affordances that work in the simple cases, but trade offs become necessary when things get more complicated.

  • Related