2

Lets say we are making an API with two resources: Author and Book where books can have many authors and authors can have many books.

So we design the REST api like so:

/books
/books/:id
/books/:id/authors
/authors
/authors/:id
/authors/:id/books

Should, for example, /books/:id return the Book with the given id and the various Authors? Or should it return the Book with the given id and the ids of the various Authors which can then be queried either via a bunch of queries to /authors/:id or /authors?ids=1,2,3, etc.?

  • 4
    /books/:id should return the Book with the given id. /books/:id/authors should return the authors of a given book. – Robert Harvey Jun 15 '18 at 22:02
7

If, instead of api endpoints, these were web pages on a web site, how would you arrange them?

If you guessed wrong, or worse yet had to somehow do it more than one way, what would you do?

In most cases, the answer is: you would create more documents, and add extra links to help people reliably find the document that is best for them.

Think about it: how many different Hemingway web pages are there on the internet?

The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain. -- Jim Webber 2011

Your REST API is an attempt to disguise your domain model as a web site. Let the web be your guide.

3

Should, for example, /books/:id return the Book with the given id and the various Authors? Or should it return the Book with the given id and the ids of the various Authors which can then be queried either via a bunch of queries to /authors/:id or /authors?ids=1,2,3, etc.?

Short story long. depends.

It depends on how you want clients ** to consume**, interact and discover books and their related resources. Whether a Book should provide clients with more or less data will depend on these things.

When the API is only feeding a single client. Let's say a mobile app or a web app, these apps act as a lighthouse. Their needs use to dictate which representation suites better to their needs for UX, usability, efficiency, etc.

It's different when we are developing a web API for multiple clients, we have to decide how we want them all to consume the API and how many requests do we want them to do for reaching all the data. Among many other things.

The business also matters. There could be other constraints as for example security. Can any user have access to the author's data? Can any user list and search authors? Are we going to allow guest users to see resources? Yes? How many data are they allowed to see? Can they update resources?

@VoinceOfUnreason already made a good point

Your REST API is an attempt to disguise your domain model as a web site. Let the web be your guide.

This's easier to conceptualize with HATEOAS

{
   "title":"The Jungle Book",
   "published":1894
   "_link":{
        "self":{ "href": "http://myserver/book/x"},
        "authors":{ "href": "http://myserver/book/x/authors"}
   },
   "_embedded":{
         "authors":[
              {
               "name": "Rudyard Kipling",
               "_links:":{ 
                  "self":{ "href": "http://myserver/author/y"},
                  "books":{ "href": "http://myserver/author/y/books"}
              }
         }
   }
}

The book's representation of /book/x would be the content for the page /book/x.page. Everything necessary for the clients to show the book as we want it to be is there. What's not, can be fetched following the _links o embedded resource's links. In other words, following the links as if it was a web page.

Of course, we could just have returned everything in a single request. However, we would have to weight first the consequences. For example, what happens when we have a collection of Books instead of a single one. How would the server behave with such need of load per book, page, etc. And with high concurrency? What about the database? How would it behave under these conditions? What if we keep adding more info to the book's representation? What if we want to remove related data? What would be less harmful, removing a block of data from book's representation or removing a link?

As you see, there are so many questions we can not answer for you. That's why is hard for us to say what should you do. It's all up to your needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.