Provide a way to send a JSON object with `WebClient`
JSON is the dominant exchange format for REST API.
However, Armeria's WebClient does not provide any JSON-specific APIs.
I believe it should be useful additions if we provide:
WebClient client = WebClient.of();
// Send a serialized JSON object with "applicaiton/json"
HttpResponse response = client.postJson("/items", new MyItem());
HttpResponse response = client.putJson("/items", new MyItem());
HttpResponse response = client.patchJson("/items", new MyItem());
HttpResponse response = client.prepare()
.post("/items")
.contentJson(new MyItem())
.execute();
~~Additionally, how do you think similar feature, HttpRequest.ofJson?~~
Additionally, how about adding HttpRequest.ofJson also?
+1 to having HttpRequest.ofJson() as well.
It would also be nice to have APIs that automatically convert a response into an object.
- Content-Type
- We can support well-known media types such as:
- "application/json"
- "application/protobuf" (We can add this later cause Protobuf is not a popular format for REST.)
- An
UnsupportedMediaTypeExceptioncould complete the returned future for unknown media types. - An
JsonProcessingExceptioncould complete the returned future when failing to decode a JSON in response body into an object.
- We can support well-known media types such as:
- Status
- The default expected HTTP response is 200 OK. If another status is received;
UnexpectedHttpStatusExceptioncould complete the returned future.- Alternatively, an additional API that can specify an expected HTTP status.
interface HttpResponse {
<T> CompletableFuture<T> aggregateAs(Class<? extends T> clazz);
<T> CompletableFuture<T> aggregateAs(HttpStatus expectedStatus, Class<? extends T> clazz);
<T> CompletableFuture<T> aggregateAs(HttpStatus expectedStatus, Class<? extends T> clazz, EventExecutor executor);
}
I'm interested in this!
Thanks! It's all yours.
@ikhoon @trustin @minwoox @jrhee17 Hi, Armeria team. Could you consider to assign this issue to me? I'd like to start a contribution with this issue. Thank you!
Sure, I think this PR still has value in:
- Adding convenience methods to send a JSON directly via WebClient
WebClient client;
HttpResponse response = client.postJson("/items", new MyItem());
HttpResponse response = client.putJson("/items", new MyItem());
HttpResponse response = client.patchJson("/items", new MyItem());
- Adding a factory method
HttpRequest.ofJsonto create a request with a JSON
HttpRequest.ofJson(obj);
cc. @ikhoon the original proposer of the issue
On second thought, returning a ResponseEntity<T> would be better for JSON exchanges.
I propose the following API style:
CompletableFuture<ResponseEntity<Result>> response = client.postJson<Result>("/items", new MyItem());
@jrhee17 @ikhoon Thank you for your opinions, jrh2217 & ikhoon. I have questions on those things.
Q1. What is a default content type & charset of the json method?
I've checked other methods on the WebClient and guess that the default charset is the UTF-8 & the default content-type is application/json, right?
Q2. Which arguments are required on the new json method?
Some methods on the WebClient have more arguments than path & content object. (ex: query params, request headers)
Do you think that the methods only need the path & content object?
Q3. Result of the json method.
Is there any convention on the WebClient?
I think there is no method that returns the CompletableFuture<ResponseEntity<T>>.
I'll choose the return type that ikhoon mentioned if there is no convention or it's more helpful to users.
Please give me your opinions~! Thank you~! 🙇♂️
guess that the default charset is the UTF-8 & the default content-type is application/json, right?
Yes
Do you think that the methods only need the path & content object?
I think just a path/content is fine for starters
I'll choose the return type that ikhoon mentioned
Sounds good to me