HATEOAS: absolute or relative URLs?

2020-02-16 07:22发布

In designing a RESTful Web Service using HATEOAS, what are the pros and cons of showing a link as a complete URL ("http://server:port/application/customers/1234") vs. just the path ("/application/customers/1234")?

标签: rest hateoas
9条回答
SAY GOODBYE
2楼-- · 2020-02-16 08:02

The only real difference would seem to be that it's easier for clients if they are consuming absolute URIs instead of having to construct them from the relative version. Of course, that difference would be enough to sway me to do the absolute version.

查看更多
3楼-- · 2020-02-16 08:02

An important consideration in large API results is the extra network overhead of including the full URI repeatedly. Believe it or not, gzip does not entirely solve this issue (not sure why). We were shocked at how much space the full URI took up when there were hundreds of links included in a result.

查看更多
The star\"
4楼-- · 2020-02-16 08:13

You should always use the full URL. It acts as the unique identifier for the resource since URLs are all required to be unique.

I would also argue that you should be consistent. Since the Location HTTP header expects a full URL based on the HTTP specification, the full URL is sent back in the Location header to the client when a new resource is created. It would be strange for you to provide a full URL in the Location header and then relative URIs in the links within your response body.

查看更多
▲ chillily
5楼-- · 2020-02-16 08:16

As your application scales, you may wish to do load balancing, fail-over, etc. If you return absolute URIs then your client-side apps will follow your evolving configuration of servers.

查看更多
虎瘦雄心在
6楼-- · 2020-02-16 08:20

Regarding the pros, I see the reduction in bytes to be transmitted at the expense of extra handling required by a client for the (absolute) path. If you are desperate to save every byte, even after trying content-encoding as gzip, proper use of caching headers, usage of etags and conditional requests on the client, then this may be necessary in the end, but I expect much higher returns on your efforts elsewere.

Regarding the cons, I see a loss of control regarding how you can direct the flow of clients between resources in the future (load balancing, A/B testing, ...), and I would consider it a bad practice regarding managing a web API. The URL you provide is no longer basically opaque for the client (see Tim Berners-Lee Axioms of Web Architecture on URI opacity). In the end, you become responsible to keep clients happy regarding their creative usage of your API, even if it is only regarding the structure of your URL space. Should you ever need to allow for a explicitly defined URL modification, consider the usage of URI templates as used in the Hypertext Application Language.

查看更多
家丑人穷心不美
7楼-- · 2020-02-16 08:25

It depends on who is writing the client code. If you are writing the client and server then it doesn't make much difference. You will either suffer the pain of building the URLs on the client or on the server.

However, if you are building the server and you expect other people to write client code then they will love you much more if you provide complete URIs. Resolving relative URIs can be a bit tricky. First how you resolve them depends on the media-type returned. Html has the base tag, Xml can have xml:base tags in every nested element, Atom feeds could have a base in the feed and a different base in the content. If you don't provide your client with explicit information about the base URI then they have to get the base URI from the request URI, or maybe from the Content-Location header! And watch out for that trailing slash. The base URI is determined by ignoring all characters to the right of the last slash. This means that trailing slash is now very significant when resolving relative URIs.

The only other issue that does require a small mention is document size. If you are returning a large list of items where each item may have multiple links, using absolute URLs can add a significant amount of bytes to your entity if you do not compress the entity. This is a perf issue and you need to decide if it is significant on a case by case basis.

查看更多
登录 后发表回答