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 and RpcRequest from RequestContext so you don’t need to downcast Request to HttpRequest or RpcRequest. #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 return null 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 #2085

      • CircuitBreaker
      • 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

    πŸ› 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 with RetryingHttpClient. #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 of pathPrefix(String prefix). #2040
    • πŸ—„ RouteBuilder.prefix(String prefix, ...) has been deprecated in favor of pathPrefix(String prefix, ...). #2040
    • πŸ—„ RouteBuilder.pathWithPrefix(String prefix, String pathPattern) has been deprecated in favor of path(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() returns HttpRequest instead of Request. #2120
      • RequestContext.updateRequest() always updates an HttpRequest. It returns void now because it never fails, unless null is specified.
      • RequestContext.newDerivedContext(Request) now requires both HttpRequest and RpcRequest.
    • 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.
    • AbstractStreamMessageDuplicator.close() does not abort all children StreamMessages. #2134
      • You should use AbstractStreamMessageDuplicator.abort() to abort all children StreamMessages anymore.

    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: