Issue 11059

Change subresource URIs

11059
Reporter: trobertson
Assignee: trobertson
Type: Improvement
Summary: Change subresource URIs
Priority: Major
Resolution: WontFix
Status: Closed
Created: 2012-05-10 13:55:39.775
Updated: 2013-12-16 17:50:44.862
Resolved: 2012-08-29 09:51:54.491
        
Description: I am looking at caching for the WS API.

I would like to propose we change the URIs for the PUT, DELETE for contact, endpoint and identifier

Currently we have:
  POST /dataset//contact     (adds a contact to the dataset)
  PUT /contact/   (updates the contact)

I propose a change so subresources are always referenced in a URI implying they are sub resources:
  POST /dataset//contact     (adds a contact to the dataset)
  PUT /dataset//contact/   (updates the contact)

Justification:
i) while the dataset/ is unnecessary in uniquely identifying the contact resource, it clearly shows the contact is a sub resource
ii) because of our eager loading in primary resources (dataset here), cache control can purge the primary by URL inspection.
  - as we are now, cache control has to "find the type of, and URI of, the primary resource for the contact"

Would anyone object to this?  If so, please provide rationale.  If you think it reasonable, please just +1 this proposal
]]>
    


Author: fmendez@gbif.org
Created: 2012-05-10 14:00:09.117
Updated: 2012-05-10 14:00:09.117
        
+1
PUT /contact/; made no sense, the same for all subresources
    


Author: kbraak@gbif.org
Comment: +1
Created: 2012-05-10 14:18:13.852
Updated: 2012-05-10 14:18:13.852


Author: mdoering@gbif.org
Comment: Reverting to our original API is ok by me, but I have to say I do not like the URI with 2 keys involved. That just seems wrong, even though all our subcomponents do know about the agents uuid, so its not problem to build the uri with just a Contact for example. Ever thought about no sub resources and making them all primary with a required networkEntityKey?
Created: 2012-05-10 14:22:54.653
Updated: 2012-05-10 14:22:54.653


Author: jcuadra@gbif.org
Created: 2012-05-10 14:25:37.501
Updated: 2012-05-10 14:25:37.501
        
+1
BTW, if we decide on  to identify contacts & identifiers & endpoints, then we would need to add an "uuid" column to the DB and api objects (Endpoints already have an "uuid" attribute in the DB but it's API object does not)
    


Author: trobertson@gbif.org
Created: 2012-05-10 14:37:45.331
Updated: 2012-05-10 14:37:45.331
        
Markus:  While it is not enforced, most things I read recommend exactly the approach I describe (presumably for the kind of reasons I am finding) which is:

  POST http://..../object
  PUT http://..../object/id

it is irrelevant what the .... is, the recommended URI design very often is to follow that approach.

E.g. from http://adam.heroku.com/past/2008/3/14/rest_enlightenment/

  POST http://myphotos.example.com/users/adam/photos adds a photo to adams photos
  PUT http://myphotos.example.com/users/adam/photos/12345

Of course this is an ROA approach, so the URI is opaque to the client, but in reality we can make our lives a lot easier with a nice URI design.

Regarding "everything as primary" we could, but then our rules for eagerly loading become quite obscure.

For now I will do the lookup against the DB, but I want to keep this issue open as we monitor progress.



    


Author: mdoering@gbif.org
Created: 2012-05-10 15:09:26.758
Updated: 2012-05-10 15:09:26.758
        
Just reading your comment tim. It makes a lot of sense to treat all resources the same for CRUD, so having a different URI for DELETE/PUT, GET and POST is nasty. We definitely should change the API to only use

POST http://..../object
GET/PUT/DELTE http://..../object/id

Question then only is if we want subresources at all.
A sub resource is nice for GETting the sublists, filtered by the main entity. But is it a good design to not have any way of listing all endpoints for example and encode a "filter" in the URI?
    


Author: trobertson@gbif.org
Created: 2012-05-10 15:14:27.605
Updated: 2012-05-10 15:14:27.605
        
So the only issue is because we have eager loading.  If we had the following kind of transaction log:

POST /dataset creates a dataset
PUT /dataset/1 updates the dataset
POST /dataset/1/contact creates a dataset contact
PUT /dataset/1/contact/1 updates a dataset contact
GET /dataset/1 returns the dataset (no notion of contacts at all in there)
GET /dataset/1/contact returns the contacts list of dataset 1

etc

The flip side of this is that remote users will spawn 1000s of requests with no eager loading.

I'll do a first cache purge based on the API as it is, and we can keep thinking on this - possibly asking for external commentary...



    


Author: trobertson@gbif.org
Comment: This was only sought after to simplify cache purging strategies, which are no longer an issue due to fast performance without a cache.
Created: 2012-08-29 09:51:54.525
Updated: 2012-08-29 09:51:54.525