3

I'm building a RESTful API that exposes my application's users as users.

My application also features 'documents' and each user has access to specific documents. I'm thinking the natural way to represent that is by exposing the accessible documents through users/{user-id}/documents.

However, from a usability perspective, it's important for my clients to be able to fetch (and modify) the users that have access to a specific document. Because of that I'm considering 'reversing' this representation to documents/{document-id}/users.

Do these (and especially the latter) seem like proper ways to model this relationship? If I do go with such a solution, how do I model 'granting access to a document'?

I'm leaning towards PUTing a pre-existing user (presumably acquired by GETing users) into documents/{document-id}/users/{user-id}. That seems unsatisfactory however, as I'll be doing an 'update' operation not to actually update the resource but to insert it into a collection. It is especially problematic in terms of semantics as I expect my server-side to ultimately not take into account the complete, sent user representation but rather only cross-reference the id with ids of pre-existing users in order to create an association.

On the other hand, I can't POST into documents/{document-id}/users as I'm not aiming at the creation of a new resource - I specifically don't want one to be created.

Am I doing it wrong?

biril
  • 1,975
  • 1
  • 19
  • 30
  • 1
    Possible duplicate of [How to handle many-to-many relationships in a RESTful API?](http://stackoverflow.com/questions/6324547/how-to-handle-many-to-many-relationships-in-a-restful-api) (although I still would be interested in opinions about how PUT / POST semantics figure into this) – biril Feb 25 '14 at 22:42

1 Answers1

1

The users don't really belong to the document resource, right? What you're really saying is these users have access to this document. So what should probably be returned from /documents/{document-id}/users is not a direct representation of the user entity, but instead some kind of representation of the user's permission to the entity. Perhaps inside of that representation is a link to the full user itself.

So, if you were returning the Collection+JSON media type, maybe you'd have something like:

{
  "collection":
  {
    "version":"1.0",
    "href":"/documents/document123",
    "items":
    [
      {
         "href":"/documents/document123/users/user3841",
         "data": [ 
                    { "name":"userName", "value":"John Doe", "prompt":"User Name" },
                    { "name":"permissions", "value":["Read"], "prompt":"User Permissions" }
                 ],         
         "links": [ 
                    { "rel":"user", "href":"/users/3841" }
                  ]
      },
      {
         "href":"http//whatever/documents/document123/users/user9387",
         "data": [ 
                    { "name":"userName", "value":"John Doe", "prompt":"User Name" },
                    { "name":"permissions", "value":["Read"], "prompt":"User Permissions" }
                 ],         
         "links": [ 
                    { "rel":"user", "href":"/users/9387" }
                  ]
      }
    ]
  }
}
Drew Marsh
  • 33,111
  • 3
  • 82
  • 100