https://github.com/nstdio/http-client-ext
Extensions to JDK's HttpClient
https://github.com/nstdio/http-client-ext
cache gzip http java json
Last synced: 6 months ago
JSON representation
Extensions to JDK's HttpClient
- Host: GitHub
- URL: https://github.com/nstdio/http-client-ext
- Owner: nstdio
- License: apache-2.0
- Created: 2021-09-04T18:26:38.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-01-25T20:40:13.000Z (about 1 year ago)
- Last Synced: 2025-01-25T21:21:38.777Z (about 1 year ago)
- Topics: cache, gzip, http, java, json
- Language: Kotlin
- Homepage:
- Size: 1.13 MB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# HttpClient Extensions
The project provides useful extensions to
JDK's [HttpClient](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html).
### Status
| Type | Status |
|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Build | [](https://github.com/nstdio/http-client-ext/actions/workflows/build.yaml) |
| Artifact | [](https://search.maven.org/search?q=g:%22io.github.nstdio%22%20AND%20a:%22http-client-ext%22) |
| Javadoc | [](https://javadoc.io/doc/io.github.nstdio/http-client-ext) |
| Code coverage | [](https://codecov.io/gh/nstdio/http-client-ext) |
| LGTM | [](https://lgtm.com/projects/g/nstdio/http-client-ext/alerts/) [](https://lgtm.com/projects/g/nstdio/http-client-ext/context:java) |
### Requirements
- Java 11+
- [Gradle](https://gradle.org/) for building the project.
### Gradle
```
implementation 'io.github.nstdio:http-client-ext:2.4.0'
```
### Maven
```
io.github.nstdio
http-client-ext
2.4.0
```
### Features
- [Caching](#Caching), both in memory and disk.
- [Decompression](#Decompression): `br, zstd, gzip, deflate`
- [JSON](#JSON) mappings
### Caching
The `ExtendedHttpClient` implements client part of [RFC7234](https://datatracker.ietf.org/doc/html/rfc7234)
There are two types of cache:
```
// backed by volotile in-memory storage
Cache mem = Cache.newInMemoryCacheBuilder().build()
// and persistent storage
Cache disk = Cache.newDiskCacheBuilder().dir(Path.of("...")).build()
```
Here is the example of creating client with in memory cache:
```java
HttpClient client = ExtendedHttpClient.newBuilder()
.cache(Cache.newInMemoryCacheBuilder().build())
.build();
URI uri = URI.create("https://api.github.com/users/defunkt");
HttpRequest request = HttpRequest.newBuilder(uri).build();
HttpResponse networkResponse = client.send(request, ofString());
HttpResponse cachedResponse = client.send(request, ofString());
```
and all available configurations for in memory cache:
```java
Cache inMemory = Cache.newInMemoryCacheBuilder()
.maxItems(4096) // number of responses can be cached
.size(10 * 1000 * 1000) // maximum size of the entire cache in bytes, -1 for no constraint
.requestFilter(request -> request.uri().getHost().equals("api.github.com")) // cache only requests that match given predicate
.responseFilter(response -> response.statusCode() == 200) // cache only responses that match given predicate
.build();
```
Above-mentioned configurations also applies to persistent cache with some additions
```java
Path cacheDir = ...
Cache disk = Cache.newDiskCacheBuilder()
.dir(cacheDir)
.build();
```
If request/response contains sensitive information one might want to store it encrypted:
```java
Path cacheDir = ...
SecretKey secretKey = ...
Cache encrypted = Cache.newDiskCacheBuilder()
.dir(cacheDir)
.encrypted()
.key(secretKey)
.cipherAlgorithm("AES")
.build();
```
will create persistent cache which encrypts data by user provided key.
### Decompression
Here is an example of transparent encoding feature
```java
HttpClient client = ExtendedHttpClient.newBuilder()
.transparentEncoding(true)
.build();
URI uri = URI.create("https://api.github.com/users/defunkt");
HttpRequest request = HttpRequest.newBuilder(uri).build();
// Client will add `Accept-Encoding: gzip, deflate` header to the request
// then decompress response body transparently of the user
HttpResponse response = client.send(request, ofString());
```
there is also dedicated `BodyHandler` for that, but in this case user should add `Accept-Encoding` header manually
```java
HttpClient client = HttpClient.newClient();
URI uri = URI.create("https://api.github.com/users/defunkt");
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Accept-Encoding", "gzip, deflate")
.build();
HttpResponse response = client.send(request, BodyHandlers.ofDecompressing(ofString()));
```
Out of the box support for `gzip` and `deflate` is provided by JDK itself. For `br` (brotli) or `zstd` compression
please add one of following dependencies to your project:
- [org.brotli:dec](https://mvnrepository.com/artifact/org.brotli/dec/0.1.2)
- [Brotli4j](https://github.com/hyperxpro/Brotli4j)
- [zstd-jni](https://github.com/luben/zstd-jni)
service loader will pick up correct dependency. If none of these preferred there is always an options to extend via [SPI](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html)
by providing [CompressionFactory](https://github.com/nstdio/http-client-ext/blob/main/src/main/java/io/github/nstdio/http/ext/spi/CompressionFactory.java)
### JSON
Currently, two libraries are supported
- [Jackson](https://github.com/FasterXML/jackson-databind)
- [Gson](https://github.com/google/gson)
just drop one of them as dependency and voilà
```java
// will create object using Jackson or Gson
User user = client.send(request, BodyHandlers.ofJson(User.class));
// or send JSON
Object user = null;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users"))
.POST(BodyPublishers.ofJson(user))
.build();
ExtendedHttpClient client = ExtendedHttpClient.newHttpClient();
HttpResponse response = client.send(request, BodyHandlers.ofJson(User.class));
```
And if special configuration required
```java
package com.example;
class JacksonMappingProvider implements JsonMappingProvider {
@Override
public JsonMapping get() {
// configure jackson
ObjectMapper mapper = ...
return new JacksonJsonMapping(mapper);
}
}
```
then standard SPI registration can be used or custom provider can be registered manually:
```java
JacksonMappingProvider jackson = ...
JsonMappingProvider.addProvider(jackson);
```