Skip to content

Commit a37cbfa

Browse files
committed
#10 - ENH: Add HttpClientContext.create() method to obtain a http client implementation
1 parent d725469 commit a37cbfa

File tree

5 files changed

+77
-0
lines changed

5 files changed

+77
-0
lines changed

client/src/main/java/io/avaje/http/client/DHttpClientContext.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.avaje.http.client;
22

33
import java.io.IOException;
4+
import java.lang.reflect.Constructor;
45
import java.net.http.HttpClient;
56
import java.net.http.HttpHeaders;
67
import java.net.http.HttpRequest;
@@ -33,6 +34,29 @@ class DHttpClientContext implements HttpClientContext {
3334
this.requestIntercept = intercept;
3435
}
3536

37+
@Override
38+
@SuppressWarnings("unchecked")
39+
public <T> T create(Class<T> clientInterface) {
40+
if (!clientInterface.isInterface()) {
41+
throw new IllegalArgumentException("API declarations must be interfaces.");
42+
}
43+
String implClassName = clientImplementationClassName(clientInterface);
44+
try {
45+
Class<?> serviceClass = Class.forName(implClassName);
46+
Constructor<?> constructor = serviceClass.getConstructor(HttpClientContext.class);
47+
Object service = constructor.newInstance(this);
48+
return (T) service;
49+
} catch (Exception e) {
50+
throw new IllegalStateException("Failed to create http client service " + implClassName, e);
51+
}
52+
}
53+
54+
private <T> String clientImplementationClassName(Class<T> clientInterface) {
55+
String packageName = clientInterface.getPackageName();
56+
String simpleName = clientInterface.getSimpleName();
57+
return packageName + ".httpclient." + simpleName + "$httpclient";
58+
}
59+
3660
@Override
3761
public HttpClientRequest request() {
3862
return new DHttpClientRequest(this, requestTimeout);

client/src/main/java/io/avaje/http/client/HttpClientContext.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ static HttpClientContext.Builder newBuilder() {
4747
return new DHttpClientContextBuilder();
4848
}
4949

50+
/**
51+
* Return the http client API implementation.
52+
*
53+
* @param clientInterface A <code>@Client</code> interface with annotated API methods.
54+
* @param <T> The service type.
55+
* @return The http client API implementation.
56+
*/
57+
<T> T create(Class<T> clientInterface);
58+
5059
/**
5160
* Create a new request.
5261
*/

client/src/test/java/io/avaje/http/client/DHttpClientContextTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.avaje.http.client;
22

3+
import org.example.github.BasicClientInterface;
34
import org.junit.jupiter.api.Test;
45

56
import java.net.http.HttpClient;
@@ -11,6 +12,12 @@ class DHttpClientContextTest {
1112

1213
private final DHttpClientContext context = new DHttpClientContext(null, null, null, null, null, null, null);
1314

15+
@Test
16+
void create() {
17+
BasicClientInterface client = context.create(BasicClientInterface.class);
18+
assertThat(client).isNotNull();
19+
}
20+
1421
@Test
1522
void gzip_gzipDecode() {
1623

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.example.github;
2+
3+
import io.avaje.http.api.Get;
4+
import io.avaje.http.api.Path;
5+
import io.avaje.http.client.HttpException;
6+
7+
import java.util.List;
8+
9+
@Path("/")
10+
public interface BasicClientInterface {
11+
12+
@Get("users/{user}/repos")
13+
List<Repo> listRepos(String user, String other) throws HttpException;
14+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.example.github.httpclient;
2+
3+
import io.avaje.http.client.HttpClientContext;
4+
import io.avaje.http.client.HttpException;
5+
import org.example.github.BasicClientInterface;
6+
import org.example.github.Repo;
7+
8+
import java.util.Collections;
9+
import java.util.List;
10+
11+
/**
12+
* Placeholder for code generated by avaje-http-client-generator.
13+
*/
14+
public class BasicClientInterface$httpclient implements BasicClientInterface {
15+
16+
public BasicClientInterface$httpclient(HttpClientContext context) {
17+
18+
}
19+
@Override
20+
public List<Repo> listRepos(String user, String other) throws HttpException {
21+
return Collections.emptyList();
22+
}
23+
}

0 commit comments

Comments
 (0)