What is the purpose of returning the “self” link in the top level “links”? Doesn’t the client already know what link it made the request to? Is it OK for the “self” link to be different from the client request, for example if the server applies URL rewrites or should the server just redirect instead in that case?
I suppose it’s so the client can pass the response on to some other application / user who can then resubmit the original request if they want to (e.g. to check if the content has changed), i.e. it avoids the client having to pass this “out of band”.
Not sure I understand how it helps the client, the client already knows what URL it requested.
And regarding my 2nd question: can the “self” link returned in the response be slightly different if the server uses URL rewrites for example? Or is it a strong requirement that the request URL must match the “self” URL in the response?
It does, but it doesn’t need to somehow add this to the API response data when it passes the information to a third party - it can just pass the response and the third party will know what request was used. I haven’t needed to use this feature yet myself, but it’s theoretically useful, and fits with the hypermedia principle of reducing the amount of out of band information.
The spec isn’t very clear on this, but it does say: “self: the link that generated the current response document.”; and if you follow the reference to
link it then says: "Each member of a links object is a “link”."
To me this suggests that a URL in the top level
self link must also be present in a
links section elsewhere in the API. But so long as the API responses consistently use the same URL (e.g.
/abc/123) I don’t think it matters whether or not some proxy server or HTTP server in front of your API translates this to another URL (e.g.
def/456) used only internally by your API implementation.
And therefore if your API is doing HATEOAS, then the request URL would also be the same as the top-level
self URL (because the client would have no way to discover any alternate URL).