Skip to content

[client] Support Generics with Jackson #553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test jackson adapter
  • Loading branch information
SentryMan committed Jan 26, 2025
commit 4d78823e39d9ee874cb04abc700a354d6eb8d0f0
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ public <T> BodyReader<List<T>> listReader(Class<T> cls) {
});
}

@SuppressWarnings("unchecked")
@Override
public <T> BodyReader<List<T>> listReader(Type type) {
return (BodyReader<List<T>>) listReaderCache.computeIfAbsent(type, aType -> {
try {
var javaType = mapper.getTypeFactory().constructType(aType);
final CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, javaType);
final ObjectReader reader = mapper.readerFor(collectionType);
return new JReader<>(reader);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}

private static class JReader<T> implements BodyReader<T> {

private final ObjectReader reader;
Expand Down
2 changes: 1 addition & 1 deletion tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
<modules>
<module>test-javalin</module>
<module>test-javalin-jsonb</module>
<module>test-client</module>
<module>test-sigma</module>
</modules>

Expand All @@ -35,6 +34,7 @@
<jdk>[21,)</jdk>
</activation>
<modules>
<module>test-client</module>
<module>test-nima</module>
<module>test-jex</module>
<module>test-nima-jsonb</module>
Expand Down
14 changes: 14 additions & 0 deletions tests/test-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<artifactId>test-client</artifactId>

<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

Expand Down Expand Up @@ -54,6 +55,19 @@
<version>1.0</version>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jex</artifactId>
<version>3.0-RC14</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-http-client-generator</artifactId>
<version>${project.version}</version>
</dependency>

</dependencies>

</project>
18 changes: 18 additions & 0 deletions tests/test-client/src/main/java/example/github/Generic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package example.github;

import java.util.List;

import io.avaje.http.api.Client;
import io.avaje.http.api.Get;
import io.avaje.http.api.Post;
//import io.avaje.http.api.Get;
//import io.avaje.http.api.Path;
import io.avaje.http.client.HttpException;

@Client
public interface Generic {

@Post("/generic")
List<GenericData<Repo>> post(GenericData<Repo> repo) throws HttpException;

}
13 changes: 13 additions & 0 deletions tests/test-client/src/main/java/example/github/GenericData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package example.github;

public class GenericData<T> {
private T data;

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}
}
22 changes: 20 additions & 2 deletions tests/test-client/src/main/java/example/github/Repo.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
package example.github;

import com.fasterxml.jackson.annotation.JsonCreator;

public class Repo {
public long id;
public String name;
private long id;
private String name;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
13 changes: 6 additions & 7 deletions tests/test-client/src/main/java/example/github/Simple.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package example.github;

//import io.avaje.http.api.Get;
//import io.avaje.http.api.Path;
import io.avaje.http.client.HttpException;

import java.util.List;

//@Path("/")
import io.avaje.http.api.Client;
import io.avaje.http.api.Get;
import io.avaje.http.client.HttpException;

@Client
public interface Simple {

//@Get("users/{user}/repos")
@Get("users/{user}/repos")
List<Repo> listRepos(String user, String other) throws HttpException;

}

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions tests/test-client/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
open module test {

requires io.avaje.http.client;
requires io.avaje.http.api;
requires com.fasterxml.jackson.databind;
requires com.google.gson;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
example.github.httpclient.GeneratedHttpComponent
90 changes: 77 additions & 13 deletions tests/test-client/src/test/java/example/github/GithubTest.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
package example.github;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import com.google.gson.Gson;

import io.avaje.http.client.BodyAdapter;
import io.avaje.http.client.HttpClient;
import io.avaje.http.client.JacksonBodyAdapter;
import io.avaje.http.client.gson.GsonBodyAdapter;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import io.avaje.jex.Jex;

import java.util.List;
class GithubTest {

import static org.assertj.core.api.Assertions.assertThat;
static Jex.Server server = null;
String url = "http://localhost:" + server.port();

class GithubTest {
@BeforeAll
static void startServer() {
server =
Jex.create()
.get(
"/users/{user}/repos",
ctx -> {
var repo = new Repo();
repo.setId(1);
repo.setName("something");
ctx.json(List.<Repo>of(new Repo()));
})
.post(
"/generic",
ctx -> {
var repo = new Repo();
repo.setId(1);
repo.setName("something");
var data = new GenericData<Repo>();
data.setData(repo);

ctx.json(List.<GenericData<Repo>>of(data));
})
.port(0)
.start();
}

@AfterAll
static void stop() {
server.shutdown();
}

@Test
void test_create() {
Expand All @@ -22,32 +61,57 @@ void test_create() {
assertThat(simple).isNotNull();
}

@Disabled
@Test
void test_with_jackson() {
assertListRepos(jacksonBodyAdapter());
}

@Disabled
@Test
void testGeneric_with_jackson() {
assertGeneric(jacksonBodyAdapter());
}

@Test
void test_with_gson() {
assertListRepos(gsonBodyAdapter());
}

private void assertListRepos(BodyAdapter bodyAdapter) {
final HttpClient client = HttpClient.builder()
.baseUrl("https://api.github.com")
.bodyAdapter(bodyAdapter)
// .requestLogging(false)
// .requestListener(new RequestLogger())
.build();
final HttpClient client =
HttpClient.builder()
.baseUrl(url)
.bodyAdapter(bodyAdapter)
// .requestLogging(false)
// .requestListener(new RequestLogger())
.build();

final Simple simple = client.create(Simple.class);

final List<Repo> repos = simple.listRepos("rbygrave", "junk");
assertThat(repos).isNotEmpty();
}

private void assertGeneric(BodyAdapter bodyAdapter) {
final HttpClient client =
HttpClient.builder()
.baseUrl(url)
.bodyAdapter(bodyAdapter)
// .requestLogging(false)
// .requestListener(new RequestLogger())
.build();

final var generic = client.create(Generic.class);

var repo = new Repo();
repo.setId(1);
repo.setName("something");
var data = new GenericData<Repo>();
data.setData(repo);

final var repos = generic.post(data);
assertThat(repos).isNotEmpty();
}

private BodyAdapter jacksonBodyAdapter() {
return new JacksonBodyAdapter();
}
Expand Down
Loading