1.25.0 release notes
22nd August 2023
🌟 New features
GraalVM Support: Armeria now provides GraalVM reachability metadata to easily build GraalVM native images. #5005
Micrometer Observation Support: Support for Micrometer Observation is added. Refer to
ObservationClient
orObservationService
for details on how to integrate with Armeria. #4659 #4980ObservationRegistry observationRegistry = ... WebClient.builder() .decorator(ObservationClient.newDecorator(observationRegistry)) ... Server.builder() .decorator(ObservationService.newDecorator(observationRegistry)) ...
WebSocket Client Support: You can now send and receive data over WebSocket using
WebSocketClient
. #4972WebSocketClient client = WebSocketClient.of("ws://..."); client.connect("/").thenAccept(webSocketSession -> { WebSocketWriter writer = WebSocket.streaming(); webSocketSessions.setOutbound(writer); outbound.write("Hello!"); Subscriber<WebSocketFrame> subscriber = new Subscriber<WebSocketFrame>() { ... } webSocketSessions.inbound().subscribe(subscriber); });
Implement gRPC Richer Error Model More Easily: You can now easily use gRPC Richer Error Model via
GoogleGrpcStatusFunction
. #4614 #4986GoogleGrpcStatusFunction statusFunction = (ctx, throwable, metadata) -> { if (throwable instanceof MyException) { return com.google.rpc.Status.newBuilder() .setCode(Code.UNAUTHENTICATED.getNumber()) .addDetails(detail(throwable)) .build(); } ... }; Server.builder().service( GrpcService.builder() .exceptionMapping(statusFunction))
Set HTTP Trailers Easily You can now easily set trailers to be sent after the data stream using
HttpRequest.of()
orHttpResponse.of()
. #3959 #4727New API for Multipart Headers: You can now retrieve headers from a multipart request in an annotated service using
MultipartFile.headers()
. #5106Access RequestLogProperty Values More Easily:
RequestLogAccess.getIfAvailable()
has been introduced, which allows users to access aRequestLogProperty
immediately if available. #4956 #4966Keep an Idle Connection Alive on PING: The
keepAliveOnPing
option has been introduced. Enabling this option will keep an idle connection alive when an HTTP/2 PING frame orOPTIONS * HTTP/1.1
is received. The option can be configured byServerBuilder.idleTimeout()
orClientFactoryBuilder.idleTimeout()
. #4794 #4806Create a StreamMessage from Future: You can now easily create a
StreamMessage
from aCompletionStage
usingStreamMessage.of()
)>. #4995More Shortcuts for PrometheusExpositionService: You can now create a
PrometheusExpositionService
without specifying the defaultCollectorRegistry
explicitly. #5134
📈 Improvements
- The number of event loops is equal to the number of cores by default when
io_uring
is used as the transport type. #5089 - You can now customize error responses when a service for a request is not found
using
ServiceErrorHandler.renderStatus()
. #4996 - Redirection for a trailing slash is done correctly even if a reverse proxy rewrites the path. #4994
DocService
now tries to guess the correct route behind a reverse proxy. #4987- The
RetentionPolicy
of@UnstableApi
annotation is nowCLASS
so that bytecode analysis tools can detect the declaration and usage of unstable APIs. #5131
🛠️ Bug fixes
GrpcService
now returns anINTERNAL
error code if an error occurs while serializing gRPC metadata. #4625 #4686DnsCache
now allows zero TTL for resolved DNS records. #5119- Armeria's DNS resolver doesn't cache a DNS whose query was timed out. #5117
- Fixed a bug where headers could be written twice if
Content-Length
was exceeded during HTTP/2 cleartext upgrade. #5113 ServiceRequestContext.localAddress()
andServiceRequestContext.remoteAddress()
now return correct values when using domain sockets in abstract namespace. #5096armeria-logback12
,armeria-logback13
, andarmeria-logback14
have been introduced for better compatibility with Logback. #5045 #5079 #5078 #5077- You can now use either an inline debug form or a modal debug form when using
DocService
. #5072 - When using Spring integrations, even if
internal-services.port
andmanagement.server.port
are set to the same value internal services are bound to the port only once. #4796 #5022 - Exceptions that occurred during a TLS handshake are properly propagated to users. #4950
AggregatedHttpObject.content()
now respects thecharset
attribute in theContent-Type
header if available. #4931 #4948- Routes with dynamic predicates are not incorrectly cached anymore. #4927 #4934
📃 Documentation
- A new page has been added which describes how to integrate Armeria with Spring Boot. #4670 #4957
- Documentation on how
Flags
work in Armeria has been added. #4870 - A new example on how to use krotoDC with Armeria has been added. #5092
☢️ Breaking changes
- The
toStringHelper()
method inDynamicEndpointGroup
has been replaced withtoString(Consumer)
to avoid exposing an internal API in the public API. #5132
🏚️ Deprecations
HttpResponse.from()
and its variants methods are deprecated. #5075- Use
HttpResponse.of()
and its variants instead.
- Use
⛓ Dependencies
- gRPC-Java 1.56.0 → 1.57.2
- GraphQL Kotlin 6.5.2 → 6.5.3
- Guava 32.0.1-jre → 32.1.2-jre
- Jakarta Websocket 2.1.0 → 2.1.1
- Kafka client 3.4.0 → 3.4.1
- Kotlin 1.8.22 → 1.9.0
- Kotlin Coroutine 1.7.1 → 1.7.3
- Logback 1.4.7 → 1.4.11
- Micrometer 1.11.1 → 1.11.3
- Netty 4.1.94.Final → 4.1.96.Final
- Protobuf 3.22.3 → 3.24.0
- Reactor 3.5.7 → 3.5.8
- Resilience4j 2.0.2 → 2.1.0
- Resteasy 5.0.5.Final → 5.0.7.Final
- Sangria 4.0.0 → 4.0.1
- scala-collection-compat 2.10.0 → 2.11.0
- Spring 6.0.9 → 6.0.11
- Spring Boot 2.7.12 → 2.7.14, 3.1.0 → 3.1.1
- Tomcat 10.1.10 → 10.1.12