On 03/03/2010 05:05 PM, Jesus M. Rodriguez wrote:
On Wed, Mar 3, 2010 at 1:25 PM, Bryan Kearneybkearney@redhat.com wrote:
Per the IRC thread. He is a complete set of proposals with any backing referneces I have for them. If we agree to any of these, I would suggest we look to implement after this sprint in order to not scuttle the work of the client guys:
1:: Plurals
No real reference, but is looks like most folks use /owners /customers /jedi instead of /owner /customer /jedum.
Not sure how the framework handles this without moving them to a new Resource class. Today we have an @Path("/owner") at the top of the OwnerResource, maybe we remove that and put @Path on individual methods otherwise, we're looking at OwnersResource, CustomersResource, JediResource (nothing to see in this one).
2:: Put and POST
I think we are are ok, here, but look at:
http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/
http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_ser...
I think we want to go with the model of PUT being idempotent, and it is used when you know "everything". If you know some thing, or need a query parameter.. it is a POST.
I'm good with that.
3:: Rest is not RPC, Resource Addresability, URL Structure
This is a crap shoot of stuff, but looking at
http://blog.linkedin.com/2009/07/08/brandon-duncan-java-one-building-consist...
- http://www.slideshare.net/calamitas/restful-best-practices (first part)
- http://code.google.com/p/django-rest-interface/wiki/BestPractices
It seems like we would want every resource would have a permanent uri which is:
/{resources1}/{id}
And that we could provide readable uris for important relationships
/{resources1}/{id}//{resources2}/{id}
and adopt the pattern that collections can be filterable based on query parameters:
/{resources1}?foo=bar
in part of this,
+1 I'm good with this as well.
PUTTING IT ALL TOGETHER
I think the following APIS which are docuemnted at:
https://fedorahosted.org/candlepin/wiki/API
would change
registerConsumer (aka POST /consumer): POST /consumers
unregisterConsumer (aka DELETE /consumer/{cosumer_uuid}): DELETE /consumers/{consumer_uuid}
syncCertificates (aka POST /consumer/{consumer_uuid}/certificates): POST /consumers/{consumer_uuid}/certificates This is a bit off standard, but I think we are ok
bind: POST /entitlement/consumer/{consumer_uuid}/product/{product_id} becomes POST /consumers/{consumer_uuid}/entitlements?product={product_id}
POST /entitlement/consumer/{consumer_uuid}/token/{registration_token} becomes POST /consumers/{consumer_uuid}/entitlements?token={registration_token} POST /entitlement/consumer/{consumer_uuid}/pool/{pool_id} becomes POST /consumers/{consumer_uuid}/entitlements?pool={pool_id} All of these should return a new entitlement
getEntitlementPools (aka GET /entitlementpools/consumer/{consumer_uuid}/ ): GET /pools?consumer={consumer_uuid}
GET /entitlement/consumer/{dbid}/: GET /consumers/{dbid}/entitlements or GET /entitlements?consumer={dbid}
GET /owner/{dbid}/entitlement: GET /owners/{dbid}/entitlements or GET /entitlements?owner=dbid
Many other changes, but all variations on the same theme.
Thoughts, Comments, Criticisms?
Next up, which can be done later, is
- HATEOAS
- Paginating Collections
- Versioning
Definitely will need versioning, because this is something we had a problem with in Spacewalk making it difficult to change APIs trying to keep them moving forward and backwards compatible at the same time.
Where would you suggest it? Would you put it into /v1/RESOURCE.... or /RESOURCE/v1/....
-- bk