HTTP Client

Yet another take on an HTTP client library.

License

License

Categories

Categories

CLI User Interface
GroupId

GroupId

com.pkulak.httpclient
ArtifactId

ArtifactId

httpclient
Last Version

Last Version

1.0.1
Release Date

Release Date

Type

Type

pom
Description

Description

HTTP Client
Yet another take on an HTTP client library.
Project URL

Project URL

https://github.com/pkulak/http-client
Project Organization

Project Organization

com.pkulak
Source Code Management

Source Code Management

https://github.com/pkulak/http-client

Download httpclient

How to add to project

<!-- https://jarcasting.com/artifacts/com.pkulak.httpclient/httpclient/ -->
<dependency>
    <groupId>com.pkulak.httpclient</groupId>
    <artifactId>httpclient</artifactId>
    <version>1.0.1</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/com.pkulak.httpclient/httpclient/
implementation 'com.pkulak.httpclient:httpclient:1.0.1'
// https://jarcasting.com/artifacts/com.pkulak.httpclient/httpclient/
implementation ("com.pkulak.httpclient:httpclient:1.0.1")
'com.pkulak.httpclient:httpclient:pom:1.0.1'
<dependency org="com.pkulak.httpclient" name="httpclient" rev="1.0.1">
  <artifact name="httpclient" type="pom" />
</dependency>
@Grapes(
@Grab(group='com.pkulak.httpclient', module='httpclient', version='1.0.1')
)
libraryDependencies += "com.pkulak.httpclient" % "httpclient" % "1.0.1"
[com.pkulak.httpclient/httpclient "1.0.1"]

Dependencies

runtime (5)

Group / Artifact Type Version
com.fasterxml.jackson.core : jackson-databind jar 2.9.7
com.google.guava : guava jar 27.0-jre
org.apache.commons : commons-pool2 jar 2.6.0
org.asynchttpclient : async-http-client jar 2.6.0
org.slf4j : slf4j-api jar 1.7.25

Project Modules

There are no modules declared in this project.

HTTP Client

A wrapper around the amazing AsyncHttpClient that uses the "mutant factory" pattern. This means that instances are immutable, and can be shared with abandon, and all modification methods return new, still immutable instances. This allows you to cascade configuration down your app as it becomes more specific.

Installation

Binaries are deployed on Maven central:

<dependency>
    <groupId>com.pkulak.httpclient</groupId>
    <artifactId>httpclient</artifactId>
    <version>1.0</version>
</dependency>

Example

// Create a single client for the entire application. This way,
// everything can share the same connection and thread pools, plus
// user-agent.
HttpClient<Object, JsonNode> client = HttpClient.createDefault()
        .setHeader(HttpHeaders.USER_AGENT, "MyApp/1.1");

// Google can handle whatever we throw at them, so we we'll set a high
// concurrency for our Google client.
HttpClient<Object, JsonNode> googleClient = client
        .url("https://www.google.com")
        .maxConcurrency(100);

// However, _our_ service was built on a TI-83, so we really need to
// take it easy.
HttpClient<Object, JsonNode> myClient = client
        .url("https://fragile.example.com")
        .maxConcurrency(2);

// Here we'll set the return type to something more specific.
HttpClient<Object, User> myUserClient = myClient.forModelType(User.class);

// If you're using header versioning, it can be helpful to have a new
// client for each HTTP method, with the proper headers and paths set
// up before hand.
HttpClient<Object, User> myGetUserClient = myUserClient
        .method("GET")
        .setPath("/users/{id}")
        .setHeader(HttpHeaders.ACCEPT, "application/vnd.myapp.users.v1+json");

// For posts we'll just peek at the status instead of waiting around
// for a body.
HttpClient<Object, Integer> myPostUserClient = myUserClient
        .method("POST")
        .setPath("/users")
        .setHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.myapp.users.v1+json")
        .statusOnly();

// Fetch a user by setting the path param and executing the request.
User user = myGetUserClient.pathParam("id", 42).execute();

user.age += 1;

// And finally, save our change.
int statusCode = myPostUserClient.execute(user);

More Examples

HttpClient<Object, JsonNode> redditClient = HttpClient.createDefault()
        .setHeader(HttpHeaders.USER_AGENT, "HttpClient/1.0 (https://github.com/pkulak/http-client)")
        .url("https://www.reddit.com/r/ripcity.json");

// There are, of course, shortcuts for the most popular HTTP methods
JsonNode threads = redditClient.get();

// And a HEAD request only gets you the headers and status
HeaderResponse headers = redditClient.head();

// Everything can also be done asynchronously
redditClient.statusOnly().deleteAsync()
        .thenAccept(status -> {
            System.out.println("the status was " + status);
        });

// If you go over your max concurrency, requests will back up in a
// queue. To avoid this and add your own back-pressure instead, wait
// before every new request; the current thread will only continue when
// there's a slot available.
HttpClient<Object, Integer> throttledReddit = redditClient.maxConcurrency(2).statusOnly();

for (int i = 0; i < 10; i++) {
    throttledReddit.await();
    throttledReddit.headAsync().thenAccept(System.out::println);
}

// When you're done, drain the queue before you exit.
throttledReddit.awaitAll();

Versions

Version
1.0.1
1.0