void4
void4

Reputation: 236

REST - dealing with sub-resource access

I'm evaluating a possible REST API design and would like to ask for feedback or best practices on ways of dealing with nested resources.

Consider the following (JSON expressed) data model of a contrived book library that is analogous to the data I'm looking at. Please ignore the fact that a book can exist without a library, etc.

{ "library-name" : "foobar",
  "rows" : 
[
  {"row-id":"1", 
   "shelves": 
      [
        {"shelf-id":"1", 
            "books": 
              [
                {
                  "book":
                    {"book-name":"abc", "author":"someone"}
                }
              ]
         }
       ]
    }
 ]
}

Suppose then that the possible REST API design is:

/library (the root API URI)
/library/{library-name}/
/library/{library-name}/{row-id}
/library/{library-name}/{row-id}/{shelf-id}
/library/{library-name}/{row-id}/{shelf-id}/{book-name}

For POST operations the server would implement functionality to allow:

There are some tradeoffs with the above:

Comments? What am I'm missing here (I have not found many examples of the above, which makes me think that it's not a common design pattern)?

Upvotes: 4

Views: 5187

Answers (1)

Ming Chan
Ming Chan

Reputation: 1948

From your description, you meant to expose ‘row’ and ‘shelf’ as the integral part of the URL, which is fine if that is your design intent. That is where your question comes in since if ‘row’ & ‘shelf’ are the integral part of the resources’ URL, then your should not do ‘so-call’ bulk POST/PUT/DELETE operations but that is fine with GET as long as the book-name is unique.

I can see you have the follow business operations

A) -Create a book at specific location

HTTP POST /library/{lib-name}/{row-id}/{shelf-id}/{book-name}
Body: {json info for the book}

B) -Get all books

//in all library        
HTTP GET /library/

//in a specific library         
HTTP GET /library/{lib-name}/ 

//in a specific row         
HTTP GET /library/{lib-name}/{row-id}/

//in a specific row & shelf         
HTTP GET /library/{lib-name}/{row-id}/{shelf-id}/

C) -Get specific book

HTTP GET /library/{lib-name}/{row-id}/{shelf-id}/{book-name}

//If the book-name or ID is unique, you can access it from the toplevel
HTTP GET /library/books/{ book-name}

If row & shelf are not important part of the URL, you will have

A) -Create a book

HTTP POST /library/{lib-name}/{book-name}
Body: {json info for the book including row & shelf}

B) -Get all books

//-in all library       
HTTP GET /library/

//-in a specific library        
HTTP GET /library/{lib-name}/ 

C) -Get specific book

//If the book-name or ID is unique, you can access it from the toplevel
HTTP GET /library/books/{ book-name}

Updated

The decision here is from the application point of view, is {row}/{shelf} critical to be exposed to the client in the URL as a way to manage the REST resources or they are merely attributes of a book.

If {row} & {shelf} are also REST resources for client to manage or are used to identify the unique path to the resources (book in this case), it makes sense to have them as part of the URL and they should be subject to constraints under REST/HATEOAS. In order words, you should not use the complex body to include all the 'sub-resources' in your POST.

GET is more subtle.

It is straightforward for GET on URL

/library/{lib-name}/{row-id}/{shelf-id}/{book-name}

GET can be applied on '/library/{lib-name}/'. In this case, the body should contain some form of structured links to the underneath resources like

[
{/library/{lib-name}/{row-id}/{shelf-id}/{book-name}}, 
{/library/{lib-name}/{row-id}/{shelf-id}/{book-name}},
 ...]

But if they are just attributes, then they could be part of the complex body since they are not adding any value from the view of either Addressability nor Links and Connectedness.

REST concerns about the following (copied from RESTful Web Services)

  • Addressability
  • Statelessness
  • Representations
  • Links and Connectedness
  • The Uniform Interface

Two great books on REST and have some discussions on the topic that you are interested in.

Upvotes: 1

Related Questions