Armeria v0.94.0 Release Notes
Release Date: 2019-10-04 // over 4 years ago-
What is Armeria?
Armeria is an open-source asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC. Its primary goal is to help engineers build high-performance asynchronous microservices that use HTTP/2 as a session layer protocol. Visit the official web site and follow @armeria_project to check out many cool features you can't find in the official gRPC/Thrift implementation or other microservice frameworks.
π New features
π You can now decorate multiple services by path mapping. See the documentation for more information. #582 #2040 #2057
ServerBuilder sb = new ServerBuilder();// Register vipService and memberService under '/users' pathsb.annotatedService("/users/vip", vipService) .annotatedService("/users/members", memberService); // Decorate all services under '/users' pathsb.decoratorUnder("/users", (delegate, ctx, req) -> { if (!authenticate(req)) { return HttpResponse.of(HttpStatus.UNAUTHORIZED); } return delegate.serve(ctx, req); });
π You can also use fluent route builder with
routeDecorator()
to decorate more than one service by path mapping.// Decorate services under '/users' path with fluent route buildersb.routeDecorator() .pathPrefix("/users") .build((delegate, ctx, req) -\> { if (!authenticate(req)) { return HttpResponse.of(HttpStatus.UNAUTHORIZED); } return delegate.serve(ctx, req); });
You can now get the current
HttpRequest
andRpcRequest
fromRequestContext
so you donβt need to downcastRequest
toHttpRequest
orRpcRequest
. #2089 #2120// Before: Request req = ctx.request();if (req instanceof HttpRequest) { RequestHeaders headers = (HttpRequest) req).headers(); }// After:RequestHeaders headers = ctx.request().headers();// Before:if (req instanceof RpcRequest) { String rpcMethod = (RpcRequest) requestContent).method(); }// After://
rpcRequest()
method will returnnull
when the request being handled is not// an RPC request or not decoded into an RPC request yet.String rpcMethod = ctx.rpcRequest().method();You can now set example headers when using
{Annotated,Grpc,Thrift}ServiceRegisrationBean
for Spring Boot integration. #2100@Beanpublic AnnotatedServiceRegistrationBean annotatedService() { return new AnnotatedServiceRegistrationBean() .setServiceName("annotatedService") .setService(new AnnotatedService()) // Add exmample headers for annotated service .addExampleHeaders("x-additional-header", "headerVal") .addExampleHeaders("get", "x-additional-header", "headerVal"); }
π You can now create the following classes using the
builder()
method instead of their*Builder
constructors. #1719 #2085CircuitBreaker
CircuitBreakerHttpClient
CircuitBreakerRpcClient
DnsAddressEndpointGroup
DnsServiceEndpointGroup
DnsTextEndpointGroup
GrpcService
Server
RetryingHttpClient
RetryingRpcClient
// Before:Server server = new ServerBuilder() .service("/hello", (ctx, req) -> HttpResponse.of(OK)) .build();// After:Server server = Server.builder() .service("/hello", (ctx, req) -> HttpResponse.of(OK)) .build();
π Improvement
- π You can use Java 9 version specific
RequestContextAwareFuture
for the recent changes of CompletableFuture API, thanks to the Multi-Release JAR Files. #1991 #2052 #2127
π Bug fixes
ResponseTimeoutException
is not logged more than once anymore when the response has been timed out. #2000 #2138- π You no longer see
AbortedStreamException
while sending long-lived requests withRetryingHttpClient
. #2134 - π You can now see a warning message when JSON request conversion fails in an annotated service. #2041 #2131
π Deprecations
- π
AbstractBindingBuilder.pathUnder(String prefix)
has been deprecated in favor ofpathPrefix(String prefix)
. #2040 - π
RouteBuilder.prefix(String prefix, ...)
has been deprecated in favor ofpathPrefix(String prefix, ...)
. #2040 - π
RouteBuilder.pathWithPrefix(String prefix, String pathPattern)
has been deprecated in favor ofpath(String prefix, String pathPattern)
. #2040 - π
new *Builder()
constructors which are mentioned in 'New Features' have been deprecated in favor of*.builder()
. #1719 #2085
π₯ Breaking changes
- π
armeria-zipkin
has been removed for further clean-up. #2120 RequestContext.request()
returnsHttpRequest
instead ofRequest
. #2120RequestContext.updateRequest()
always updates anHttpRequest
. It returnsvoid
now because it never fails, unlessnull
is specified.RequestContext.newDerivedContext(Request)
now requires bothHttpRequest
andRpcRequest
.
- 0οΈβ£ A default virtual host service can serve any virtual host requests. #2057 #2040
- Before: If a custom virtual host fails to match the given request to a service, it returns
NOT_FOUND
status. - After: If a custom virtual host fails to match the given request to a service, looking up a default virtual host services to match the request.
- Before: If a custom virtual host fails to match the given request to a service, it returns
AbstractStreamMessageDuplicator.close()
does not abort all childrenStreamMessage
s. #2134- You should use
AbstractStreamMessageDuplicator.abort()
to abort all childrenStreamMessage
s anymore.
- You should use
Dependencies
- gRPC 1.23.0 -> 1.24.0
- β¬οΈ Dropwizard Metrics 4.0.0 -> 4.1.0
- Jetty 9.4.20.v20190813 -> 9.4.21.v20190926
- Jackson 2.9.9.20190807 -> 2.10.0
- Java JWT 3.8.2 -> 3.8.3
- Micrometer 1.2.1 -> 1.3.0
Thank you
π This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests: