-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[http-client] Add SingleBodyAdapter for client API with only a single…
… body type (#533) This provides a way to minimise the dependencies of an HttpClient that only has a single body type to support.
- Loading branch information
Showing
7 changed files
with
246 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
http-client/src/main/java/io/avaje/http/client/DSingleAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package io.avaje.http.client; | ||
|
||
import io.avaje.http.client.SingleBodyAdapter.JsonBodyAdapter; | ||
import io.avaje.json.simple.SimpleMapper; | ||
|
||
import java.util.List; | ||
|
||
@SuppressWarnings("unchecked") | ||
final class DSingleAdapter implements BodyAdapter { | ||
|
||
private final ReaderWriter<?> adapter; | ||
|
||
static BodyAdapter of(SimpleMapper.Type<?> jsonType) { | ||
return new DSingleAdapter(toAdapter(jsonType)); | ||
} | ||
|
||
static BodyAdapter of(JsonBodyAdapter<?> source) { | ||
return new DSingleAdapter(source); | ||
} | ||
|
||
private DSingleAdapter(JsonBodyAdapter<?> source) { | ||
this.adapter = new ReaderWriter<>(source); | ||
} | ||
|
||
private static <T> JsonBodyAdapter<T> toAdapter(SimpleMapper.Type<T> jsonType) { | ||
return new SimpleJsonAdapter<>(jsonType); | ||
} | ||
|
||
@Override | ||
public <T> BodyWriter<T> beanWriter(Class<?> aClass) { | ||
return (BodyWriter<T>) adapter; | ||
} | ||
|
||
@Override | ||
public <T> BodyReader<T> beanReader(Class<T> aClass) { | ||
return (BodyReader<T>) adapter; | ||
} | ||
|
||
@Override | ||
public <T> BodyReader<List<T>> listReader(Class<T> aClass) { | ||
return (BodyReader<List<T>>) adapter; | ||
} | ||
|
||
private static final class ReaderWriter<T> implements BodyReader<T>, BodyWriter<T> { | ||
|
||
private final JsonBodyAdapter<T> adapter; | ||
|
||
ReaderWriter(JsonBodyAdapter<T> adapter) { | ||
this.adapter = adapter; | ||
} | ||
|
||
@Override | ||
public T readBody(String content) { | ||
return adapter.fromJsonString(content); | ||
} | ||
|
||
@Override | ||
public T read(BodyContent bodyContent) { | ||
return adapter.fromJsonBytes(bodyContent.content()); | ||
} | ||
|
||
@Override | ||
public BodyContent write(T bean, String contentType) { | ||
return BodyContent.asJson(adapter.toJsonBytes(bean)); | ||
} | ||
|
||
@Override | ||
public BodyContent write(T bean) { | ||
return BodyContent.asJson(adapter.toJsonBytes(bean)); | ||
} | ||
} | ||
|
||
private static final class SimpleJsonAdapter<T> implements JsonBodyAdapter<T> { | ||
|
||
private final SimpleMapper.Type<T> jsonType; | ||
|
||
public SimpleJsonAdapter(SimpleMapper.Type<T> jsonType) { | ||
this.jsonType = jsonType; | ||
} | ||
|
||
@Override | ||
public T fromJsonString(String json) { | ||
return jsonType.fromJson(json); | ||
} | ||
|
||
@Override | ||
public T fromJsonBytes(byte[] bytes) { | ||
return jsonType.fromJson(bytes); | ||
} | ||
|
||
@Override | ||
public byte[] toJsonBytes(T bean) { | ||
return jsonType.toJsonBytes(bean); | ||
} | ||
} | ||
} | ||
|
54 changes: 54 additions & 0 deletions
54
http-client/src/main/java/io/avaje/http/client/SingleBodyAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package io.avaje.http.client; | ||
|
||
import io.avaje.json.simple.SimpleMapper; | ||
|
||
/** | ||
* A BodyAdapter that supports converting the request/response body to a single type. | ||
* <p> | ||
* Useful for an endpoint that only returns a single JSON response type. | ||
*/ | ||
public interface SingleBodyAdapter extends BodyAdapter { | ||
|
||
/** | ||
* Create with an json content adapter for a single java type. | ||
* | ||
* @param jsonAdapter The adapter to use to read and write the body content. | ||
* @return The BodyAdapter that the HttpClient can use. | ||
*/ | ||
static BodyAdapter create(JsonBodyAdapter<?> jsonAdapter) { | ||
return DSingleAdapter.of(jsonAdapter); | ||
} | ||
|
||
/** | ||
* Create using an avaje-json-core simple mapper type. | ||
* | ||
* @param jsonType The only type supported to read or write the body content. | ||
* @return The BodyAdapter that the HttpClient can use. | ||
*/ | ||
static BodyAdapter create(SimpleMapper.Type<?> jsonType) { | ||
return DSingleAdapter.of(jsonType); | ||
} | ||
|
||
/** | ||
* Json body reading and writing for a single type. | ||
* | ||
* @param <T> The Java type of the request or response body. | ||
*/ | ||
interface JsonBodyAdapter<T> { | ||
|
||
/** | ||
* Read the raw content String and return the java type. | ||
*/ | ||
T fromJsonString(String json); | ||
|
||
/** | ||
* Read the raw content bytes and return the java type. | ||
*/ | ||
T fromJsonBytes(byte[] bytes); | ||
|
||
/** | ||
* Write the java type to bytes. | ||
*/ | ||
byte[] toJsonBytes(T bean); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
http-client/src/test/java/io/avaje/http/client/HelloDtoAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package io.avaje.http.client; | ||
|
||
import io.avaje.json.JsonAdapter; | ||
import io.avaje.json.JsonReader; | ||
import io.avaje.json.JsonWriter; | ||
import io.avaje.json.node.JsonNodeMapper; | ||
import io.avaje.json.node.JsonObject; | ||
import org.example.webserver.HelloDto; | ||
|
||
import java.time.Instant; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
|
||
final class HelloDtoAdapter implements JsonAdapter<HelloDto> { | ||
|
||
private final JsonNodeMapper nodeMapper; | ||
|
||
HelloDtoAdapter() { | ||
nodeMapper = JsonNodeMapper.builder().build(); | ||
} | ||
|
||
@Override | ||
public void toJson(JsonWriter writer, HelloDto value) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public HelloDto fromJson(JsonReader reader) { | ||
JsonObject jsonObject = nodeMapper.objectMapper().fromJson(reader); | ||
|
||
int id = jsonObject.extract("id", 0); | ||
String name = jsonObject.extract("name", ""); | ||
String otherParam = jsonObject.extract("otherParam", ""); | ||
|
||
var hello = new HelloDto(id, name, otherParam); | ||
UUID gid = jsonObject.extractOrEmpty("gid") | ||
.map(UUID::fromString) | ||
.orElse(null); | ||
hello.setGid(gid); | ||
|
||
String when = jsonObject.extract("whenAction", (String) null); | ||
if (when != null) { | ||
hello.setWhenAction(Instant.parse(when)); | ||
} | ||
return hello; | ||
} | ||
} |
12 changes: 6 additions & 6 deletions
12
http-client/src/test/java/org/example/github/RepoJsonAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters