-
Notifications
You must be signed in to change notification settings - Fork 924
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 ResponseEntity
in annotated service instead of HttpResult
#5586
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5586 +/- ##
============================================
+ Coverage 73.95% 74.13% +0.18%
- Complexity 20115 21020 +905
============================================
Files 1730 1820 +90
Lines 74161 77443 +3282
Branches 9465 9901 +436
============================================
+ Hits 54847 57415 +2568
- Misses 14837 15378 +541
- Partials 4477 4650 +173 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work, @moromin! Left some minor comments 🙇
core/src/main/java/com/linecorp/armeria/common/ResponseEntityUtil.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/annotation/ResponseConverterFunction.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/annotation/ResponseConverterFunction.java
Outdated
Show resolved
Hide resolved
core/src/test/java/com/linecorp/armeria/common/ResponseEntityUtilTest.java
Outdated
Show resolved
Hide resolved
core/src/test/java/com/linecorp/armeria/common/ResponseEntityUtilTest.java
Outdated
Show resolved
Hide resolved
@Get("/expect-unauthorized") | ||
public ResponseEntity<HttpResponse> expectUnauthorized() { | ||
// Will send '401 Unauthorized' because the content of ResponseEntity is HttpResponse. | ||
return ResponseEntity.of( | ||
ResponseHeaders.of(HttpStatus.OK), | ||
HttpResponse.of(HttpStatus.UNAUTHORIZED)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we raise an exception to avoid this confusing behavior? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also warning, but I think the exception is more kind.
If we do, I think we could throw the exception here with the warning.
armeria/core/src/main/java/com/linecorp/armeria/internal/server/annotation/AnnotatedService.java
Lines 210 to 213 in a13d582
if (HttpResponse.class.isAssignableFrom(clazz) || | |
AggregatedHttpResponse.class.isAssignableFrom(clazz)) { | |
logger.warn("{} in the return type '{}' may take precedence over {}.", | |
clazz.getSimpleName(), returnType, HttpResult.class.getSimpleName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I see. We already log a warning message. Let's leave it as it is for now given that it may break an existing application. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last comment 😄
core/src/main/java/com/linecorp/armeria/internal/server/annotation/AnnotatedService.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏👏👏
Regarding the test failure of Maybe Gradle's build result had not been properly cleared somehow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! I hope to see you often even after Armeria Sprint. 😆
final ResponseHeadersBuilder builder = result.headers().toBuilder(); | ||
|
||
if (builder.status().isContentAlwaysEmpty()) { | ||
return builder.build(); | ||
} | ||
if (builder.contentType() != null) { | ||
return builder.build(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Micro optimization) Should we lazily create ResponseHeadersBuilder
?
ResponseHeaders headers = result.headers();
if (builder.status().isContentAlwaysEmpty()) {
return headers;
}
if (builder.contentType() != null) {
return headers;
}
....
338849a
to
cf0e9ca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left one nit but looks good overall! 👍
/** | ||
* Utilities for {@link ResponseEntity}. | ||
*/ | ||
public final class ResponseEntityUtil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit; if this class is moved to com.linecorp.armeria.internal.server.annotation
, it can be package private
public final class ResponseEntityUtil { | |
final class ResponseEntityUtil { |
/** | ||
* Build {@link ResponseHeaders} from the given {@link ServiceRequestContext} and {@link ResponseEntity}. | ||
*/ | ||
public static ResponseHeaders buildResponseHeaders(ServiceRequestContext ctx, ResponseEntity<?> result) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public static ResponseHeaders buildResponseHeaders(ServiceRequestContext ctx, ResponseEntity<?> result) { | |
static ResponseHeaders buildResponseHeaders(ServiceRequestContext ctx, ResponseEntity<?> result) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @moromin! 👍
* upstream/main: Allow `{Service,Server}ErrorHandler.renderStatus()` to access `ServiceRequestContext` (line#5634) Bump com.gradle.enterprise from 3.16.2 to 3.17 (line#5559) Bump com.gradle.common-custom-user-data-gradle-plugin from 2.0 to 2.0.1 (line#5618) Add SchemeAndAuthority class which is in charge of authority normalization (line#5561) [Issue-5581] Change into transitive dependency(netty.transport.native.unix.common) (line#5623) Make @description annotation at super class/interface work (line#5562) Support `ResponseEntity` in annotated service instead of `HttpResult` (line#5586) Update public suffix list (line#5625) Wait until buffers are released in `ExceedingServiceMaxContentLengthTest.maxContentLength` (line#5600) Add the release note for 1.28.2 (line#5615) Fixed bug where a request timeout is scheduled after receiving the entire body (line#5614) Support custom json marshaller for unframed gRPC error (line#5555) Update public suffix list (line#5612)
…line#5586) Motivation: We have `HttpResult<T>` and `ResponseEntity<T>`, both of them support automatic JSON deserialization. However, we can't use `HttpResult` for clients because it is located in `com.linecorp.armeria.server.annotation`. So, we should support `ResponseEntity` in that package so that users are not confused as to which one to use, and so that it can be used commonly between server and client. Modifications: - Add logic to check if result type is `ResponseEntity`. - Create `ResponseEntityUtil` to build response headers as well as `HttpResult`. - Deprecate `HttpResult`. - Tests - Add `ResponseEntity` cases for the cases that verify `HttpResult` behavior itself. - Replace for the cases that use `HttpResult` to verify other behaviors. Result: - Closes line#4910
Motivation:
We have
HttpResult<T>
andResponseEntity<T>
, both of them support automatic JSON deserialization.However, we can't use
HttpResult
for clients because it is located incom.linecorp.armeria.server.annotation
.So, we should support
ResponseEntity
in that package so that users are not confused as to which one to use, and so that it can be used commonly between server and client.Modifications:
ResponseEntity
.ResponseEntityUtil
to build response headers as well asHttpResult
.HttpResult
.ResponseEntity
cases for the cases that verifyHttpResult
behavior itself.HttpResult
to verify other behaviors.Result:
ResponseEntity
in annotated services. #4910