HttpClient BaseAddress path merging
Just a few days ago I was troubleshooting some integration tests which turned out to be failing because of incorrectly set BaseAddress
in the HttpClient
class. This wasn't the first time a similar thing happened to me so I decided to write a blog post about it as a future reference for me, my team and anybody else who might find it useful.
The HttpClient
client class has a BaseAddress
property which you can set so that you only need to specify the remaining relative part of the URL for individual requests. However, it's important to understand how the merging of the base address and the request URL works in order to avoid being surprised by the resulting URL.
The documentation for the BaseAddress
property states:
Note that all characters after the right-most
/
in the base URI are excluded when combined with the message URI. See RFC 3986 Uniform Resource Identifier (URI) Generic Syntax specification.
The relevant part of the linked specification says the following about path merging:
return a string consisting of the reference's path component appended to all but the last segment of the base URI's path (i.e., excluding any characters after the right-most
/
in the base URI path, or excluding the entire base URI path if it does not contain any/
characters).
What exactly does this mean for you? For the request URL to be appended to the base address, as you most likely expect, you need to make sure that:
- the base address ends with a
/
, and - the request URL starts without a
/
.
The following table shows how the values get combined with all 4 possible combinations of trailing and leading /
characters:
Base address | Request URL | Merged URL |
---|---|---|
base1/base2/ |
request |
base1/base2/request |
base1/base2/ |
/request |
request |
base1/base2 |
request |
base1/request |
base1/base2 |
/request |
request |
How to best memorize that? I find it enough to remember the following:
- Starting
/
character indicates an absolute URL. It will always overwrite everything but the host if you append it to another URL. - URLs without a trailing
/
mean that the last segment is a file, not a folder. When appending another path to such a URL, the file part will be overwritten, only the folder part will be kept.
You can find a sample project in my GitHub repository with a test that demonstrates the path merging as described in the table above.
The behavior of path merging in HttpClient
class might surprise you. However, it is implemented according to a well documented internet standard. A different behavior would certainly be surprising to an even larger number of people.