Skip to content
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

Support RxJava-wrapped HttpResult response in annotated services #5386

Merged
merged 5 commits into from
Jan 24, 2024

Conversation

KarboniteKream
Copy link
Contributor

@KarboniteKream KarboniteKream commented Jan 17, 2024

Motivation:

When returning Single<HttpResult<T>> from an annotated service, the response is always serialized as {}, since we currently just try to serialize HttpResult with Jackson. Instead, we should convert it to HttpResponse and only do serialization on HttpResult.content().

Modifications:

  • Create HttpResultUtil with the logic needed to build HttpResponse headers from HttpResult
  • Apply the same HttpResult conversion logic from AnnotatedService to CompositeResponseConverterFunction

Result:

@@ -62,6 +63,12 @@ public HttpResponse convertResponse(ServiceRequestContext ctx,
if (result instanceof HttpResponse) {
return (HttpResponse) result;
}
if (result instanceof HttpResult) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with the converter setup, so I'm not 100% sure if this is the only guaranteed entrypoint to the converter chain where we might receive an HttpResult.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the place to put logic because we don't support the conversion recursively.

import io.reactivex.rxjava3.core.Single;

@ProducesJson
public class ReactiveService {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary service for testing purposes. I still need to test Mono, but I want to figure out how to apply the converters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just leave it as TODO.
I thought we already had something like ReactorResponseConverterFuction but we don't have.
We can implement it later when we need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see! I've just tested an API that returns Mono and it indeed seems like that's not implemented yet.

Copy link
Contributor

@minwoox minwoox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologize for the late review. The changes look good to me. 👍

@@ -62,6 +63,12 @@ public HttpResponse convertResponse(ServiceRequestContext ctx,
if (result instanceof HttpResponse) {
return (HttpResponse) result;
}
if (result instanceof HttpResult) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the place to put logic because we don't support the conversion recursively.

import io.reactivex.rxjava3.core.Single;

@ProducesJson
public class ReactiveService {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just leave it as TODO.
I thought we already had something like ReactorResponseConverterFuction but we don't have.
We can implement it later when we need it.

@KarboniteKream KarboniteKream changed the title Support wrapped HttpResult response in annotated services Support RxJava-wrapped HttpResult response in annotated services Jan 22, 2024
Comment on lines +41 to +46
final AnnotatedService service = ctx.config().service().as(AnnotatedService.class);
if (service != null) {
builder.status(service.defaultStatus());
} else {
builder.status(HttpStatus.OK);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing that changed from the original implementation in AnnotatedService

@KarboniteKream KarboniteKream marked this pull request as ready for review January 22, 2024 03:10
@KarboniteKream
Copy link
Contributor Author

Seems like adding mockito-inline breaks KeepAliveHandlerTest 🤔 Let me find a different approach.

Copy link
Contributor

@minwoox minwoox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add tests that check if the following types are converted correctly?
CompletableFuture<HttpResult> and Single<HttpResult>

@minwoox minwoox added this to the 1.27.0 milestone Jan 22, 2024
Copy link
Contributor

@minwoox minwoox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!!! Thanks a lot, @KarboniteKream! 😄

Copy link
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for reporting/fixing this issue @KarboniteKream 🙇 👍 🙇

@@ -398,7 +402,7 @@ private HttpResponse convertResponse(ServiceRequestContext ctx, @Nullable Object

if (result instanceof HttpResult) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note; Perhaps in the future we may just remove this block since CompositeResponseConverterFunction has this logic already.

I understand this can't be removed this iteration due to breaking changes though

Copy link
Contributor

@minwoox minwoox Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried that but it fails depends on the implementation:

when (result) {
is Bar -> responseConverter.convertResponse(ctx, headers, "hello, bar!", trailers)
else -> ResponseConverterFunction.fallthrough()
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I also checked that the content unwrapping logic is the reason for the failure

result = httpResult.content();

Copy link
Contributor

@ikhoon ikhoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix! ❤️💯

@ikhoon ikhoon merged commit c20e058 into line:main Jan 24, 2024
13 checks passed
@KarboniteKream KarboniteKream deleted the fix/http-result-rxjava branch January 24, 2024 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Annotated services do not work with Single<HttpResult<T>>
4 participants