Collections and the use of DELETE

95 views
Skip to first unread message

Jeffrey Haynes

unread,
Feb 18, 2016, 12:16:12 PM2/18/16
to API Craft
We are trying to decide on how we handle removing a resource from a collection (not the actual deletion of the resource in the system, but removing the association from the collection).  I have perused the group a bit, but did not find an answer to this, but if I missed it, please feel free to point me to that answer.

For example:
  • resource: /accounts
  • collection: /accounts/{id}/contacts
    • The semantics of contacts are the list of current person objects where the current date is within the valid_from date and valid_to date on each object.
When we delete a contact, we must be able to specify an end date.
 
Here are the options we have come up with..

PUT /accounts/{id}/contacts/{contact_id}  payload contains the updated: valid_to 
DELETE /accounts/{id}/contacts/{contact_id} deletes the reference to the account

POST /accounts/{id}/contacts/{contact_id}/remove  payload contains the updated: valid_to deletes the reference to the account

DELETE /accounts/{id}/contacts/{contact_id}?end_date=<date> Use the query parameter to set the valid_to and then remove the reference to the account

PATCH /accounts/{id}/contacts/{contact_id} payload would be a patch payload to update the valid_to date and delete the reference to to the account

Because we add to this collection with

POST /accounts/{id}/contacts

it seems to make sense to remove the item from the collection using

DELETE /accounts/{id}/contacts/{contact_id}?end_date=<date>

But the issue is that we must be able to set the date to a date different than the current date. 

So, I am asking this here to see what the consensus is - if there is one.

Thanks,

Jeff


Jørn Wildt

unread,
Feb 21, 2016, 3:57:03 PM2/21/16
to api-...@googlegroups.com
I have come to the conclusion that if you need anything extra in addition to the main action (deleting an item, paying for something, closing an issue or similar) then POST with a payload is the way to go.

The URL should point to a "processing resource" that takes care of your request. This makes the action more visible to developers and allows them to GET the resource in order to get a description of what sort of processing the resource takes care of.

So POST /accounts/{id}/contacts/{contact_id}/remove would be my choice. I cannot tell if there is any consensus for it.

/Jørn


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at https://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Manu Whig

unread,
Feb 22, 2016, 5:06:14 AM2/22/16
to API Craft
I would prefer 
PUT /accounts/{id}/contacts/{contact_id}  payload contains the updated: valid_to
because you are in essence updating the contact-account association and specifying that the association is no longer valid at some future time, specified in the valid_to.

If you want to simply break the association then and there, use DELETE /accounts/{id}/contacts/{contact_id}  and have the service automatically record the time the association was broken.

Manu Whig

unread,
Feb 22, 2016, 5:17:15 AM2/22/16
to API Craft
Cannot seem to edit my post. Just wanted to add the following:

Your services will need to then handle the use case of returning only those contact-account associations that have a valid_to time in the future when doing a GET /accounts/{id}, GET /accounts/{id}/contacts or <HTTP VERB> /accounts/{id}/contacts/{id}

Or better yet, provide a query param allowing clients the control over which contacts for an account they want. 
GET /accounts{id}/contacts?valid=true (or get creative with date math as values for the valid param)

Jeffrey Haynes

unread,
Feb 22, 2016, 2:52:38 PM2/22/16
to API Craft
Thanks for your reply.

Will you please expand your thoughts on what lead you to the conclusion of using a POST?

Thanks
Jeff

Jeffrey Haynes

unread,
Feb 22, 2016, 2:55:24 PM2/22/16
to API Craft
DELETE would work fine if we did not need to include an end_date. However, we must account for that possibility.

I personally don't like the PUT option because the operation is not a complete update of the contact_id. I know there is debate on the semantics of PUT, but that is one reason why we don't want to use PUT in this case.

Thanks,
Jeff

Jeffrey Haynes

unread,
Feb 22, 2016, 2:57:52 PM2/22/16
to API Craft
Thanks for the clarification.

Yes, our services will work the way you describe. In our case, the contacts and contacts/{id} would only be returned if the objects are valid for the current date.

Kijana Woodard

unread,
Feb 22, 2016, 3:03:24 PM2/22/16
to api-...@googlegroups.com
There's not really a debate on the semantics of PUT unfortunately. I wish it was more about idempotency, but, as has been discussed here before, the emphasis is on full replacement.

For DELETE, you can include the end_date as a parameter.

Overall, I prefer Jørn's approach.

Jørn Wildt

unread,
Feb 22, 2016, 3:58:39 PM2/22/16
to api-...@googlegroups.com
Kijana> For DELETE, you can include the end_date as a parameter.

The problem is though that /accounts/{id}/contacts/{contact_id} is *not* the same resource as /accounts/{id}/contacts/{contact_id}?end_date=xxx - so in essence you will be deleting a different resource than you intended.

Jeffrey> Will you please expand your thoughts on what lead you to the conclusion of using a POST?

All of the arguments presented so far :-) PUT is targeted at "full replacement" of some resource, DELETE does not take a payload, GET is supposed to be "safe" and without (visible) side-effects. PATCH could be used with a patch document that included a "remove" operation of the link between the account and the contact plus a "add" operation with the end date. But my personal opinion is that it would be rather weird - and no hypermedia format so far is able to describe possible PATCH operations. That leaves POST is a viable candidate.

/Jørn


Kijana Woodard

unread,
Feb 22, 2016, 4:03:45 PM2/22/16
to api-...@googlegroups.com
I posted that as a way around the "no body for DELETE" issue. Not something I would advise. I rank it as problematic as "update date field field and PUT".

Manu Whig

unread,
Feb 22, 2016, 8:30:53 PM2/22/16
to API Craft
I prefer PUT because what is being PUT/updated is the contact-account association, not the contact. You are in fact updating the the association and the way chosen is by updating a value on the Contact resource. 
I was thinking more along the lines of the association itself was modeled as a resource, say something like {account: <href>, contact:<href>, validFrom: <date>, valid_to:<date> }, then the PUT would be the right way IMO. Unless, you also want to keep a history of the Account-Contact associations :)

But either way is fine, as long as you stick with the same convention throughout your API.
Reply all
Reply to author
Forward
0 new messages