In a proper REST API design, we use the DELETE HTTP verb to delete items by ID:
DELETE /resources/{id}
Deleting a list of IDs could look like:
DELETE /resources/{id1},{id2},{id3}
Or as a list of query string parameters:
DELETE /resources?ids=id1,id2,id3
What if the list of items to delete is really large? Meaning, what if clients need to delete items by specifying thousands of IDs?
We then run into URI length limits, so the above options will not be enough.
One way of dealing with this would be to avoid the issue using deletion by some criteria, e.g. tags.
DELETE /resources?tag=items-to-delete
But what if we really have no choice but to delete a very large ad-hoc unpredictable list specified by the client?
The following design can work well. Since DELETE does not have a body, we can use POST.
Because the verb POST no longer properly reflects the action being performed by the API, we can add a sub-resource named /bulk-deletion under resources:
POST /resources/bulk-deletion { "idsToDelete": [ id1, id2, id3, id4, ..., idN ] }
As a variation, the sub-resource could be /deletion-list or even /ids-to-delete:
POST /resources/ids-to-delete { "ids": [ id1, id2, id3, id4, ..., idN ] }
This way our limit on the number of IDs is the POST body size limit, so the design can handle a very long list.
The path makes the operation unambiguous and also keeps the route name as a noun so we avoid action names in the URI.