10.2.x Release Notes

Akka Http 10.2 is a modernization release to improve the integration with the latest Akka versions, streamline APIs, and improve performance.

Since the original release of 10.1, the Akka project has introduced a few important features:

  • Akka 2.6 offers typed actors and ActorSystems
  • Akka Stream APIs were improved to work without requiring a Materializer in most cases
  • Akka gRPC 1.0 has been released which is built on top of Akka HTTP

Akka Http 10.2.0 supports these changes in the following ways:

  • Http APIs now work the same whether a classic or a typed ActorSystem is provided
  • A new concise API for binding servers has been introduced
  • A new set of directives handle, and handleSync provide more options to seamlessly mix Akka gRPC generated service handlers with Akka Http routes. HTTP/2 support has been improved based on Akka gRPC usage.
  • Akka HTTP now supports Akka Coordinated Shutdown for server bindings.

Notable changes

Seamless integration with Akka 2.6 and new server API entrypoints

Making changes to support Akka 2.6 better, we realized that the existing server API is sometimes awkward to use and to evolve. Therefore, we took the opportunity to come up with a new ServerBuilder API that provides a way to bind servers more concisely, especially from Java.

Code like:

Scala
// only worked with classic actor system
implicit val system = akka.actor.ActorSystem("TheSystem")
implicit val mat: Materializer = ActorMaterializer()
val route: Route =
  get {
    complete("Hello world")
  }
Http().bindAndHandle(route, "localhost", 8080)
Java
// only worked with classic actor system
akka.actor.ActorSystem system = akka.actor.ActorSystem.create("TheSystem");
Materializer mat = ActorMaterializer.create(system);
Route route = get(() -> complete("Hello World!"));
Http.get(system).bindAndHandle(route.flow(system), ConnectHttp.toHost("localhost", 8080), mat);

can now be written as:

Scala
// works with both classic and typed ActorSystem
implicit val system = akka.actor.typed.ActorSystem(Behaviors.empty, "TheSystem")
// or
// implicit val system = akka.actor.ActorSystem("TheSystem")

// materializer not needed any more

val route: Route =
  get {
    complete("Hello world")
  }
Http().newServerAt("localhost", 8080).bind(route)
Java
// works with classic or typed actor system
akka.actor.typed.ActorSystem system = akka.actor.typed.ActorSystem.create(Behaviors.empty(), "TheSystem");
// or
// akka.actor.ActorSystem system = akka.actor.ActorSystem.create("TheSystem");

// materializer not needed any more

Route route = get(() -> complete("Hello World!"));
Http.get(system).newServerAt("localhost", 8080).bind(route);

Notably, server written with the routing DSL will now be automatically converted to an asynchronous handler (using the new pendant of bindAndHandleAsync) instead of being provided as a Flow (using bindAndHandle before). This has the benefit that it fits the style of the routing DSL better which really represents an asynchronous handler function and, more importantly, will enable routes to work automatically with HTTP/2 (when enabled).

The old APIs have been deprecated but will be kept for binary and source compatibility at least until 10.3 but maybe even longer (because they have been such a central part).

We made an effort to keep supporting Akka 2.5.x (>= 2.5.31) for this release to ease the migration burden. It required backporting some features from Akka 2.6 so that seamless APIs would work the same with Akka 2.6 and Akka 2.5. The 10.2.x release line will be the last supporting Akka 2.5.

For the final 10.2.0 release we strive to release a scalafix rule for making the transition as painless as possible.

Attributes for HttpRequest and HttpResponse

In many cases metadata needs to be attached to a HTTP message. Previously, this was accomplished by introducing synthetic headers to add to requests and responses. However, this was more of a workaround that could lead to confusion about which headers should be rendered and where they originated. Akka Http 10.2 introduces attributes to HTTP messages. These allow attaching and querying typed metadata values to messages.

See Attributes for more information.

Default configuration improvements

Seldom used features have now been turned off by default:

  • Transparent HEAD support was disabled, see #2088 and the migration notes for information about the rationale.
  • Server-side HTTP pipelining was disabled by default. Common HTTP clients do not support it by default or have it disabled, so to reduce complexity in the common code paths the default akka.http.server.pipelining-limit was changed to 1. See the migration notes for more information.

Better support for upcoming Scala versions

Scala 2.13 deprecated “adapted arguments” which were heavily used in the routing DSL with the magnet pattern. It allowed that you could have a method with a single argument to take any number of arguments in a typesafe fashion by relying on the Scala compiler to convert those arguments to a tuple of arguments. Since a while we generally try to reduce our usage of implicits and the magnet pattern to avoid complex compile error messages, long compile times, and complexity. With Akka Http 10.2 we made another effort to reduce our dependency on that language feature by providing a set of code-generated overloads for the methods in question to pave our way for upcoming Scala versions.

See the migration guide for more information.

Client: configurable setting overrides per target host

It is now possible to set overrides for client settings per target host via configuration. For example, if you use Akka HTTP client to access different services, it is now possible to tweak pool and connection parameters like the maximum number of concurrent connections (max-connections) on a per-target-host-basis. Thanks to David Knapp / @Falmarri for providing an initial implementation of that feature a long time ago.

Client: custom client DNS resolution transport

By default, host name resolution is done in the IO layer when a connection attempt is made. In some cases, it can make sense to be able to customize the resolution, for example if there are multiple ip addresses returned for a DNS query, this could be used to implement custom DNS load balancing schemes. For that purpose, a new ClientTransport.withCustomResolver was introduced that allows providing custom resolution for each connection attempt.

See the section about custom client DNS resolution schemes for more information.

Performance improvements

  • Better performance for big client pools: Big client pools with more than 500 connections (max-connections = 500 or more) suffered from a bad choice of datastructure with O(n²) access times, so bigger pools spent too much time just sifting through the internal data structures instead of doing useful work. This has been fixed and a nightly benchmark has been set up to track performance going forward.
  • Cheaper logging in client pools helps pools of all sizes by avoiding logging when DEBUG logging is disabled.
  • discardEntityBytes for strict entities is now a no-op while before streams were materialized.

Streamlined HTTPS configuration

Akka HTTP no longer uses the HTTPS configuration configured with ssl-config by default. Instead, it will use the JRE defaults for client connections. For server connections you should create a HttpsConnectionContextHttpsConnectionContext with the relevant configuration.

See Configuring HTTPS connections for more information.

Other changes

Migration notes

See the Migration guide.

Changes since 10.1.11

akka-http-core

  • Fix cancellation race conditions on the client-side #2965
  • Silence outgoing request stream error #2905
  • Add SameSite attribute to Cookies #2928
  • Only catch NonFatal Exceptions #2853
  • Add coordinated shutdown support #3142
  • Percent-encode illegal chars when creating URI query #3003
  • Add the remote address in parse errors when possible #2899
  • Remove UseHttp2 #2896
  • Hide body and headers by default in HttpRequest#toString and HttpResponse#toString #2560
  • Fix headers javadsl scaladoc #2932
  • Allow client setting overrides for target hosts in config #2574
  • Fix EOL detection for body part parsing #2581
  • Update javadsl bindAndHandle to take a Java function and System #3223
  • Identify Content-Type charset parameter even if not lower case #2926
  • Prevent initialization NPE which might fail all retries quickly #2958
  • Add exclusion for Extension issues when building against Akka 2.6 #2945
  • Nest correctly in NewHostConnectionPool #2964
  • Support for request/response message attributes #2938
  • Don’t fail slot after previous connection failed in special condition #3021
  • Simplify route2HandlerFlow #2893
  • Better support for the new Actors API #3036
  • Parse empty query ? to Query.empty #3042
  • Make sure to cancel response entity on failure #3046
  • Add akka.http.server.remote-address-attribute #2924
  • Make transparent-head-requests opt-in #3063
  • Continue more gracefully when encountering multiple Host headers in a response #3158
  • Allow customizing parsing errors #3049
  • Don’t extend from Char => Boolean for CharPredicate #3107
  • Add server-side streamCancellationDelay to mitigate cancellation race conditions #2116
  • Improve error message about unconsumed entity #3109
  • Header rendering with less indirection #3106
  • Remove deprecated methods taking implicit materializers #3119
  • Simplify superPool and clientFlow #3156
  • Deprecate Remote-Address header #3174
  • Move max-content-length definition from top to server/client #3098
  • Add test for failure propagation into websocket flows #3276
  • Deprecate UpgradeToWebSocket #3278, #3296
  • Disable server-side HTTP pipelining by default#
  • Make HttpEntity.Strict.discardBytes a no-op #3329
  • Make sure to reset all UriParser fields before reusing#
  • Track idle slots explicitly to avoid O(n^2) work for big pools#
  • Keep request/response copy method public #3347
  • Introduce javadsl discardEntityBytes that takes a ClassicActorSystemProvider#
  • Provide toStrict overloads with ClassicActorSystemProvider parameter#
  • Introduce custom hostname resolution client transport #3202
  • Avoid expensive logging in NewHostConnectionPool #3356
  • Introduce Http().newServerAt server builder API#
  • Make HttpRequest/HttpResponse.hashCode depend on attributes #3351

akka-http

  • Allow names as alternative to directive combiners #3085
  • Names for symbolic enhancements #3082
  • Allow names to match paths #3089
  • Remove deprecated FormFieldDirectives methods #3120
  • Remove magnets usage from formField directives #3289
  • Provide Route.toFunction as alternative to Route.asyncHandler #3115
  • New handle directive to create Route from function #3239
  • Allow ‘bindAndHandleAsync’ to take a ‘Route’ #3237
  • Make X-Real-IP take precedence over Remote-Address #3173
  • Allow passing a companion object to headerValueByType #3279
  • Replace magnetic parameter overloads by boilerplate-generated overloads #2971
  • Deprecate directives taking Symbol as argument #3291
  • Remove uploadedFile (deprecated in 10.0.11) #3118
  • Deprecate internal parts of coding infrastructure #3262
  • Deprecate HttpApp #3162
  • Allow ‘complete’ directive with status without adapted arguments #3307
  • Fix remaining internal adapted arguments warnings #3337
  • Create Unmarshaller.unmarshal overloads taking in ClassActorSystemProvider#
  • Add directives for extracting attributes #3355
  • Document and dogfood using the attribute for websockets #3358
  • Add handlePF directive #3367

akka-http-marshallers

  • Only show unmarshalling error details when ‘verbose-error-messages’ is on #3265
  • Jackson: Better JSON validation error when unmarshalling #2901

akka-http-testkit

  • Allow RouteTest to run integration tests via ~!> operator #3014
  • Update to Scalatest 3.1.0 #2851
  • Handle test exceptions separately from regular exceptions #2949
  • Simplify implicits for RouteTest #3060
  • Fix more Scala 2.13 warnings #3130

docs

  • Use typed ActorSystem in examples #3242
  • Routing DSL style guide #3099
  • Routing DSL compared with Play routes #3079
  • Small typo in docs/src/main/paradox/common/marshalling.md #2864
  • Add warning on usage on extractClientIP #2922
  • Show RequestBuilding in client examples #2968
  • Don’t claim that SNI is a security feature #3257
  • Update documentation and examples to Akka 2.6 #2996
  • Link to major/minor Akka docs #3048
  • Actor interop Java example #3078
  • Make Case class extraction example work with 2.13 #3092
  • Fix more Scala 2.13 warnings #3130
  • Update extractClientIP.md wrt remote-address-attribute #3083
  • Make HttpServerWithActorsSample more 2.6-style #3077
  • Show symbolic Akka version for dependencies #3121
  • Support native ALPN in JDK >=8u251 #3117
  • Use automatic root dir resolution for snip and signature #3339
  • Page about client-side configuration + per-host-overrides #3338
  • Document and dogfood using the attribute for websockets #3358
  • Add ‘troubleshooting’ page, populate with ‘PRI’ error message #3384

akka-http2-support

  • Initial HTTP/2 client implementation bits #3166
  • Potential fix for idle timeouts in http2 #2776
  • Frame parsing: improve handling of unknown values #3101
  • Support native ALPN in JDK >=8u251 #3117
  • Fix HeaderCompression updating table size without giving notice to peer #2891
  • Reduce http2 buffer debug logging #3025
  • Accept RST on an already-half-closed HTTP/2 stream #2976
  • Gracefully discard unsupported h2 SETTINGS #3053
  • Make the HTTP/2 Stream ID an attribute #3224

akka-http-caching

  • Harden ExpiringLfuCacheSpec #2960

build

  • Fix project-info links to API docs #2857
  • Drop Scala 2.11 #2589
  • Build with Scala 2.13 by default #3126
  • Better diagnostics when validatePullRequest fails weirdly #2904
  • Test against published snapshots instead of source deps #3055
  • Enable some fatal warnings for docs #3114
  • Add sbt-reproducible-builds #3165
  • Publish docs from travis #3328
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.