okhttp vs JVM built-in HttpClient
okhttp was my go-to library when writing a http client code
for JVM. However, since Java 9 there’s a built-in java.net.http.HttpClient
.
Feature-wise and API-wise it compares very well against okhttp - it’s really usable, supports async
out-of-the-box and is baked-in in JVM by default, as opposed to okhttp (which also brings in additional dependency on okio).
You can check out the HttpClient overview on Baeldung; the HttpClient javadoc is very well written and contains examples to get you started quickly.
The only disadvantage is the missing URIBuilder, and a bit of bare-bones API.
URIBuilder
URIBuilder is useful when you need to programmatically create the URI, e.g. programmatically add query parameters and escape them correctly. URIBuilder is unfortunately not baked in JVM. Fear not, there are these solutions:
- Use the apache-uribuilder library. It’s a fork of Apache HttpCore5 but with just the URIBuilder part.
- Alternatively, this urlbuilder project looks good too.
- Alternatively use http4k with a bit of error-checking code
There are other ways of getting the URIBuilder class, but they’re inferior:
- Apache HttpCore5 (sources on github) offers URIBuilder. It doesn’t require any additional dependencies, which is great; but the jar itself is 900kb long. Still, this is the best way to go forward at the moment.
- There’s a rs URIBuilder baked in JavaEE7, but that also brings tons of deps
- Spring has URIBuilder too, but that also brings tons of deps
- URIBuilder-tiny lacks support for duplicate query parameters, useful e.g. when you need to create a filter query such as
http://foo.com/rest/person?age=lt:30&age=gt:20
. See #7. - uri-builder-java is barebones and doesn’t even support escaping
- httpcache4j uribuilder is immutable which is just plain dumb to create an immutable builder (which is by definition a mutable builder used to build immutable objects).
Usage Tips
Android
What about Android? The java.net.http.HttpClient
is missing; Android instead packages
Apache HttpClient by default. The quality of that one is unknown, but I’m not sure whether
it’s portable to JDK. Everyone else seems to be using okhttp, so I’ll go with that for the time being.
Beware: okhttp 3.13+ requires Android 5.0 (SDK 21); you can use 3.12+ but it lacks support for TLS 1.2+. I think that everyone switched to Android 5.0 already, so going with okhttp 4+ is probably a good choice.