postgrest
postgrest copied to clipboard
Add support for bulk-delete
Closes #2314
- [x] Full support for bulk-delete
- [x] Modify error message from 204 to 422 when body is missing/empty
- [x] Tests
- [x] Refactor
- [x] Changelog
After much deliberation, the changes implemented are as follows:
- Deletes now allow filters (equality only) in the body. That is:
Gives the same result as:DELETE /table {"col1": "val1", "col2": "val2"}
DELETE /table?col1=eq.val1&col2=eq.val2
- Bulk deletes behave in the same way (body used as filters in the
WHERE
clause), differentiating themselves from the behaviors withPATCH
(body used for values in theSET
clause) orPOST
(body used for values to be inserted). - Using
?columns
circumvent the parsing of the json body, which verifies that all the objects have the same keys, and uses only the specified columns as filters in the query. - DELETE without filters/body/limits/columns (full table delete) is not allowed and throw an HTTP 422 error.
- ~If there are filters or limits specified in the query string, then the body will be ignored (for both single object and bulk DELETE).~
I think we can close https://github.com/PostgREST/postgrest/issues/699 once this is merged(and continue the cancel request part on https://github.com/PostgREST/postgrest/issues/2352)
As it is, one deficiency of the new bulk delete(and bulk update suffers from something similar too) is that it doesn't fail with an appropriate message when no filters or body are specified, it just returns 204. This is desirable as discussed on the issues, but it is surprising for someone that hasn't read our docs.
Do you think it would be possible to respond with a 422 when no filters, limits or body are present?
For when a body is present, it might be possible to also count the pks in the body on the query and then verify this count is > 0 to fail with the same error(this could be adopted for PATCH too).
Hm, I've been thinking that this one could also be done with underscore operators. Like:
DELETE /tbl?id=_in.body->ids
{ "ids": [1,2,3,4]}
I guess one problem with that approach would be how to compare two values that are on the same json object, which this PR already does. For underscore operators, I'm not sure if this would be possible:
DELETE /tbl?col1=_eq.body->*->col1&col2=_eq.body->*->col2
[
{"col1": "val1", "col2": "val2"}
, {"col1": "val3", "col2": "val4"}
]
The *
is borrowed from JSON path's [*]
which means get keys from all array elements.
Closed in favor of https://github.com/PostgREST/postgrest/pull/2724