Skip to content

avaje/avaje-http-client

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

avaje-http-client

A light weight wrapper to the JDK 11+ Java Http Client

  • Adds a fluid API for request constructing URL and payload
  • Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson
  • Adds request/response logging

Dependency

<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>avaje-http-client</artifactId>
  <version>1.6</version>
</dependency>

Create HttpClientContext

Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON body adapter, logger.

  public HttpClientContext client() {
    return HttpClientContext.newBuilder()
      .withBaseUrl(baseUrl)
      .withRequestListener(new RequestLogger())
      .withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
//      .withBodyAdapter(new GsonBodyAdapter(new Gson()))
      .build();
  }

Requests

From HttpClientContext:

  • Create a request
  • Build the url via path(), matrixParam(), queryParam()
  • Optionally set headers(), cookies() etc
  • Optionally specify a request body (JSON, form, or raw BodyPublisher)
  • Http verbs - GET(), POST(), PUT(), PATCH(), DELETE(), HEAD(), TRACE()
  • Optionally return response body as a bean, list of beans, or raw

Examples

GET as String

HttpResponse<String> hres = clientContext.request()
  .path("hello")
  .GET()
  .asString();

GET as json to single bean

Customer customer = clientContext.request()
  .path("customers").path(42)
  .GET()
  .bean(Customer.class);

GET as json to a list of beans

List<Customer> list = clientContext.request()
  .path("customers")
  .GET()
  .list(Customer.class);

GET as application/x-json-stream as a stream of beans

Stream<Customer> stream = clientContext.request()
  .path("customers/all")
  .GET()
  .stream(Customer.class);

POST a bean as json request body

HelloDto bean = new HelloDto(12, "rob", "other");

HttpResponse<Void> res = clientContext.request()
  .path("hello/savebean")
  .body(bean)
  .POST()
  .asDiscarding();

assertThat(res.statusCode()).isEqualTo(201);

Path

HttpResponse<String> res = clientContext.request()
  .path("customers")
  .path("42")
  .path("contacts")
  .GET()
  .asString();

// is the same as ...

HttpResponse<String> res = clientContext.request()
  .path("customers/42/contacts")
  .GET()
  .asString();

MatrixParam

HttpResponse<String> httpRes = clientContext.request()
  .path("books")
  .matrixParam("author", "rob")
  .matrixParam("country", "nz")
  .path("foo")
  .matrixParam("extra", "banana")
  .GET().asString();

QueryParam

List<Product> beans = clientContext.request()
  .path("products")
  .queryParam("sortBy", "name")
  .queryParam("maxCount", "100")
  .GET().list(Product.class);

FormParam

HttpResponse<Void> res = clientContext.request()
  .path("register/user")
  .formParam("name", "Bazz")
  .formParam("email", "user@foo.com")
  .formParam("url", "http://foo.com")
  .formParam("startDate", "2020-12-03")
  .POST()
  .asDiscarding();

assertThat(res.statusCode()).isEqualTo(201);

Currently, NO support for POSTing multipart-form

Auth token

Built in support for obtaining and setting an Authorization token.

1. Implement AuthTokenProvider

  class MyAuthTokenProvider implements AuthTokenProvider {

    @Override
    public AuthToken obtainToken(HttpClientRequest tokenRequest) {
      AuthTokenResponse res = tokenRequest
        .url("https://foo/v2/token")
        .header("content-type", "application/json")
        .body(authRequestAsJson())
        .POST()
        .bean(AuthTokenResponse.class);

      Instant validUntil = Instant.now().plusSeconds(res.expires_in).minusSeconds(60);

      return AuthToken.of(res.access_token, validUntil);
    }
  }

2. Register with HttpClientContext

    HttpClientContext ctx = HttpClientContext.newBuilder()
      .withBaseUrl("https://foo")
      .withBodyAdapter(new JacksonBodyAdapter(objectMapper))
      .withRequestListener(new RequestLogger())
      .withAuthTokenProvider(new MyAuthTokenProvider()) <!-- HERE
      .build();

3. Token obtained and set automatically

Now all requests using the HttpClientContext will automatically get an Authorization header with Bearer token added. The token will be obtained when necessary.