[rest-practices] Modelling membership

Mark McLoughlin markmc at redhat.com
Tue May 4 13:19:02 UTC 2010


Hey,

We're just hitting something in rhevm-api which I think is fairly
generic. So, I'll use a simple user/groups example instead of a RHEV
specific example.

A user may be a member of multiple groups. We have a top-level /users
collection and a top-level /groups collection. How do we modelling
adding a user to a group?

 1) a <users> element under <group>

    One thing we didn't like about this is race conditions when editing 
    the membership list using PUT - e.g. A and B see list as { bob,
    bill, bryan }, client A adds { eoghan } and client B adds { mark }.
    The result is dependent on which client posts last

    Eoghan suggests investigating whether a client could specify Etag 
    in its PUT to mean "only accept the update if the current content 
    matches this etag". If it fails, the client would re-GET, re-do its 
    edit and re-PUT.

 2) a /users/ collection under a group

    e.g. <group><link rel="users" href="/group/1234/users"/></group>

    Adding a user would be:

      POST /group/1234/users

      <user id="5678"/>

      HTTP/1.1 201 Created
      Location: /group/1234/users/5678

    We liked this because we wanted a per-group user URI. See[1]

    It also gave a nice solution to the concurrency issue above.

    We didn't like the fact that it was ambiguous whether the POST 
    should create a new user or just add an existing user to the 
    group's users collection.

    Also, in general, there is less expressiveness possible with 
    POSTing to a collection rather than adding to a list - e.g. you 
    can't order the elements in the collection with POST.

Any thoughts?

Thanks,
Mark.
   
[1] - this is where things get messy. Instead of "group" read "data
center" and instead of "user" read "storage domain"

A storage domain can be attach to multiple data centers. In the current
RHEV-M API, a storage domain's state is dependent on which data center
you are viewing it from

e.g. a storage domain can be "attached" in one data center and "active"
in another data center. If you query a storage domain outside of the
context of a data center its status is "mixed"

So, we're modelling that as:

  /datacenters/1111/storagedomains/5678 state = "attached"
  /datacenters/2222/storagedomains/5678 state = "active"
  /storagedomains/5678 state = "mixed"




More information about the rest-practices mailing list