I'm working on a SPA which is a client to a RESTful web service. Both the client and server are part of the same project, i.e. I can modify the code for both sides freely. I've been reading up on RESTful API design to try and make sure I'm doing everything the "right" way. One of my takeaways from reading is that a RESTful service should publish hyperlinks so clients can access more information, and that clients should have no hardcoded information about service URLs other than an entry point. Using hyperlinks allows the client to be more flexible in the event that the server makes URL changes.
However I can't figure out how this architecture is supposed to work when users are allowed to link to a specific client state. For example:
One of the views is a list of books available for purchase. The client sets the browser's location to /books/
to identify this page, and the backend data comes from an endpoint /api/books/
, retrieved from an API entry point that publishes that URL. The service URL responds with a JSON document like this:
[
{"title": "The Great Gatsby",
"id": 24,
"url": "http://localhost/api/books/24/"},
< and so on >
]
The client uses this to generate readable links that, when clicked, go to a detailed view of a single book. The browser's location is updated to /books/the-great-gatsby/24/
so users can bookmark this view and link to it.
How does the client handle when users click this link directly?? How would it know where to get the information for this book without having a hardcoded URL?
The best I could come up with is the following sequence of requests:
GET /api/
- view which services are available (to find there are books at all)OPTIONS /api/books/
- view a description of what operations are available on books (so e.g. it can make sure it can find books by ID)GET /api/books/?id=24
- See if it can find a book with an ID that matches the ID in the browser's location.GET /api/books/24/
- Actually retrieve the data
Anything shorter would imply that the client has hardcoded knowledge of the API's URLs. However, from a web app point of view, this seems grossly inefficient.
Is there some trick I'm missing? Is there a way for the client to "know" how to get more detail about book ID 24 without somehow having the /api/books/24/
endpoint hardcoded?
http://localhost/api/books/24/
in this case? – Oxide/books/the-great-gatsby/24/
view. – Physicisthttp://localhost/api/books/24/
as alink
tag in itshead
– Oxide