pekko/akka-docs/rst/java/http/common/marshalling.rst

167 lines
7.9 KiB
ReStructuredText
Raw Normal View History

!htp #18919 #19519 New JavaDSL for Akka HTTP (#20518) * !htt #18919 #19519 Align Java HTTP server DSL with Scala This commits replaces the Java HTTP server DSL with a Java-8 centric one which exposes all scala DSL concepts to be usable from Java, including custom directives, (un)marshallers, rejections, headers, and type safety for path and query parameters. * Add RequestContext and RouteResult to Java DSL fix websockets WIP bring java docs up to date. This applies some updates to the root-level documentation * [htp] Fix java documentation to correctly mention timeouts Timeouts are configured the same in Java and Scala. Hence, linking to the scala docs for timeouts from Java. * =htc fix optionalHeaderValueByType in Java * =htt #20200 fix java testkit always using NoLogging instead logger * +htt actually run new javadsl tests, allow overriding config * =htt improve javadsl test infra with more details when fails * =htt fix bug in wrong path matcher exposed * +htp add missing remaining path matcher * =htp Java DSL cookie tests fixed * =htt Java DSL ParameterDirectivesTest fixed Protect the tweets from scalariform Incorrect response expectations in cache condition directives spec fixed * =htt Path directives for Java DSL * +!htt PathMatchers rewritten, made uniform and tests passing * Bugfix in java reject and a little test-boyscouting * Revert "Incorrect response expectations in cache condition directives spec fixed" This reverts commit cd50e89d45db010309f8249b090ea654ebb11c7a. * +htc HttpAPIsTest is compile time only, not for running Also, moved from the client package since not strictly a client test. SecurityDirectives passing Two faulty tests and two actual bugs. Fix for cache condition spec not working * Not sending in Unit instad of the implicit magnet in the test * HeaderMagnet now works as expected * Java API added for - and + on DateTime PetStore example and test fixed * Annotations to make marshalling work without default constructor * Made model class immutable Incorrect tests fixed Some scaladoc boyscouting as bonus * =htt RequestValTest sprinkled out across multiple directive tests Client ip extraction test with incorrect header name fixed. * =htt Incorrect CodingDirectivesTest fixed. * =htt Bugfix for Java Unmarshaller.firstOf and fixes to JavaRouteTest * =htt MarshallerTest fixed * Missing seal signature added to JavaDSL * More consistent (with Scala) test kit setup for Java * missing Javadocs added * Thread.sleep in default exception handler removed * =htt copy directive docs, prepare for finishing it up * +htt SecurityDirectives.authorize variants and test coverage added * +htt Custom headers in Java DSL * =htt WIP on java docs * +htp add missing parameterOrDefault directive Fixed a lot of doc warnings * =htc intense progress on javadsl docs * =htc #20470 Link to issue about docs and fix compile error compile, migration guide don't mima check http-experimental * =htt Java DSL doc warnings fixed. Only `Could not lex literal_block` ones left now * =htc fix mima settings * =doc fix MethodDirectives doc test with custom method * =htc fix coding directives spec after bad merge * =htc fix concat being corresponding to route() in javadsl * =htt Disable consistency check for route/concat as it fails only on ci server * !htt Minor fixes to PathMatchers
2016-05-16 10:38:40 +02:00
.. _http-marshalling-java:
Marshalling
===========
TODO overhaul for Java
"Marshalling" is the process of converting a higher-level (object) structure into some kind of lower-level
representation, often a "wire format". Other popular names for it are "Serialization" or "Pickling".
In Akka HTTP "Marshalling" means the conversion of an object of type ``T`` into a lower-level target type,
e.g. a ``MessageEntity`` (which forms the "entity body" of an HTTP request or response) or a full ``HttpRequest`` or
``HttpResponse``.
Basic Design
------------
Marshalling of instances of type ``A`` into instances of type ``B`` is performed by a ``Marshaller[A, B]``.
Akka HTTP also predefines a number of helpful aliases for the types of marshallers that you'll likely work with most:
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/marshalling/package.scala
:snippet: marshaller-aliases
Contrary to what you might initially expect ``Marshaller[A, B]`` is not a plain function ``A => B`` but rather
essentially a function ``A => Future[List[Marshalling[B]]]``.
Let's dissect this rather complicated looking signature piece by piece to understand what marshallers are designed this
way.
Given an instance of type ``A`` a ``Marshaller[A, B]`` produces:
1. A ``Future``: This is probably quite clear. Marshallers are not required to synchronously produce a result, so instead
they return a future, which allows for asynchronicity in the marshalling process.
2. of ``List``: Rather than only a single target representation for ``A`` marshallers can offer several ones. Which
one will be rendered onto the wire in the end is decided by content negotiation.
For example, the ``ToEntityMarshaller[OrderConfirmation]`` might offer a JSON as well as an XML representation.
The client can decide through the addition of an ``Accept`` request header which one is preferred. If the client doesn't
express a preference the first representation is picked.
3. of ``Marshalling[B]``: Rather than returning an instance of ``B`` directly marshallers first produce a
``Marshalling[B]``. This allows for querying the ``MediaType`` and potentially the ``HttpCharset`` that the marshaller
will produce before the actual marshalling is triggered. Apart from enabling content negotiation this design allows for
delaying the actual construction of the marshalling target instance to the very last moment when it is really needed.
This is how ``Marshalling`` is defined:
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/marshalling/Marshaller.scala
:snippet: marshalling
Predefined Marshallers
----------------------
Akka HTTP already predefines a number of marshallers for the most common types.
Specifically these are:
- PredefinedToEntityMarshallers_
- ``Array[Byte]``
- ``ByteString``
- ``Array[Char]``
- ``String``
- ``akka.http.scaladsl.model.FormData``
- ``akka.http.scaladsl.model.MessageEntity``
- ``T <: akka.http.scaladsl.model.Multipart``
- PredefinedToResponseMarshallers_
- ``T``, if a ``ToEntityMarshaller[T]`` is available
- ``HttpResponse``
- ``StatusCode``
- ``(StatusCode, T)``, if a ``ToEntityMarshaller[T]`` is available
- ``(Int, T)``, if a ``ToEntityMarshaller[T]`` is available
- ``(StatusCode, immutable.Seq[HttpHeader], T)``, if a ``ToEntityMarshaller[T]`` is available
- ``(Int, immutable.Seq[HttpHeader], T)``, if a ``ToEntityMarshaller[T]`` is available
- PredefinedToRequestMarshallers_
- ``HttpRequest``
- ``Uri``
- ``(HttpMethod, Uri, T)``, if a ``ToEntityMarshaller[T]`` is available
- ``(HttpMethod, Uri, immutable.Seq[HttpHeader], T)``, if a ``ToEntityMarshaller[T]`` is available
- GenericMarshallers_
- ``Marshaller[Throwable, T]``
- ``Marshaller[Option[A], B]``, if a ``Marshaller[A, B]`` and an ``EmptyValue[B]`` is available
- ``Marshaller[Either[A1, A2], B]``, if a ``Marshaller[A1, B]`` and a ``Marshaller[A2, B]`` is available
- ``Marshaller[Future[A], B]``, if a ``Marshaller[A, B]`` is available
- ``Marshaller[Try[A], B]``, if a ``Marshaller[A, B]`` is available
.. _PredefinedToEntityMarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/marshalling/PredefinedToEntityMarshallers.scala
.. _PredefinedToResponseMarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/marshalling/PredefinedToResponseMarshallers.scala
.. _PredefinedToRequestMarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/marshalling/PredefinedToRequestMarshallers.scala
.. _GenericMarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/marshalling/GenericMarshallers.scala
Implicit Resolution
-------------------
The marshalling infrastructure of Akka HTTP relies on a type-class based approach, which means that ``Marshaller``
instances from a certain type ``A`` to a certain type ``B`` have to be available implicitly.
The implicits for most of the predefined marshallers in Akka HTTP are provided through the companion object of the
``Marshaller`` trait. This means that they are always available and never need to be explicitly imported.
Additionally, you can simply "override" them by bringing your own custom version into local scope.
Custom Marshallers
------------------
Akka HTTP gives you a few convenience tools for constructing marshallers for your own types.
Before you do that you need to think about what kind of marshaller you want to create.
If all your marshaller needs to produce is a ``MessageEntity`` then you should probably provide a
``ToEntityMarshaller[T]``. The advantage here is that it will work on both the client- as well as the server-side since
a ``ToResponseMarshaller[T]`` as well as a ``ToRequestMarshaller[T]`` can automatically be created if a
``ToEntityMarshaller[T]`` is available.
If, however, your marshaller also needs to set things like the response status code, the request method, the request URI
or any headers then a ``ToEntityMarshaller[T]`` won't work. You'll need to fall down to providing a
``ToResponseMarshaller[T]`` or a ``ToRequestMarshaller[T]`` directly.
For writing your own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly.
!htp #18919 #19519 New JavaDSL for Akka HTTP (#20518) * !htt #18919 #19519 Align Java HTTP server DSL with Scala This commits replaces the Java HTTP server DSL with a Java-8 centric one which exposes all scala DSL concepts to be usable from Java, including custom directives, (un)marshallers, rejections, headers, and type safety for path and query parameters. * Add RequestContext and RouteResult to Java DSL fix websockets WIP bring java docs up to date. This applies some updates to the root-level documentation * [htp] Fix java documentation to correctly mention timeouts Timeouts are configured the same in Java and Scala. Hence, linking to the scala docs for timeouts from Java. * =htc fix optionalHeaderValueByType in Java * =htt #20200 fix java testkit always using NoLogging instead logger * +htt actually run new javadsl tests, allow overriding config * =htt improve javadsl test infra with more details when fails * =htt fix bug in wrong path matcher exposed * +htp add missing remaining path matcher * =htp Java DSL cookie tests fixed * =htt Java DSL ParameterDirectivesTest fixed Protect the tweets from scalariform Incorrect response expectations in cache condition directives spec fixed * =htt Path directives for Java DSL * +!htt PathMatchers rewritten, made uniform and tests passing * Bugfix in java reject and a little test-boyscouting * Revert "Incorrect response expectations in cache condition directives spec fixed" This reverts commit cd50e89d45db010309f8249b090ea654ebb11c7a. * +htc HttpAPIsTest is compile time only, not for running Also, moved from the client package since not strictly a client test. SecurityDirectives passing Two faulty tests and two actual bugs. Fix for cache condition spec not working * Not sending in Unit instad of the implicit magnet in the test * HeaderMagnet now works as expected * Java API added for - and + on DateTime PetStore example and test fixed * Annotations to make marshalling work without default constructor * Made model class immutable Incorrect tests fixed Some scaladoc boyscouting as bonus * =htt RequestValTest sprinkled out across multiple directive tests Client ip extraction test with incorrect header name fixed. * =htt Incorrect CodingDirectivesTest fixed. * =htt Bugfix for Java Unmarshaller.firstOf and fixes to JavaRouteTest * =htt MarshallerTest fixed * Missing seal signature added to JavaDSL * More consistent (with Scala) test kit setup for Java * missing Javadocs added * Thread.sleep in default exception handler removed * =htt copy directive docs, prepare for finishing it up * +htt SecurityDirectives.authorize variants and test coverage added * +htt Custom headers in Java DSL * =htt WIP on java docs * +htp add missing parameterOrDefault directive Fixed a lot of doc warnings * =htc intense progress on javadsl docs * =htc #20470 Link to issue about docs and fix compile error compile, migration guide don't mima check http-experimental * =htt Java DSL doc warnings fixed. Only `Could not lex literal_block` ones left now * =htc fix mima settings * =doc fix MethodDirectives doc test with custom method * =htc fix coding directives spec after bad merge * =htc fix concat being corresponding to route() in javadsl * =htt Disable consistency check for route/concat as it fails only on ci server * !htt Minor fixes to PathMatchers
2016-05-16 10:38:40 +02:00
Rather, it should be possible to use one of the convenience construction helpers defined on the ``Marshaller``
companion:
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/marshalling/Marshaller.scala
:snippet: marshaller-creation
Deriving Marshallers
--------------------
Sometimes you can save yourself some work by reusing existing marshallers for your custom ones.
The idea is to "wrap" an existing marshaller with some logic to "re-target" it to your type.
In this regard wrapping a marshaller can mean one or both of the following two things:
- Transform the input before it reaches the wrapped marshaller
- Transform the output of the wrapped marshaller
For the latter (transforming the output) you can use ``baseMarshaller.map``, which works exactly as it does for functions.
For the former (transforming the input) you have four alternatives:
- ``baseMarshaller.compose``
- ``baseMarshaller.composeWithEC``
- ``baseMarshaller.wrap``
- ``baseMarshaller.wrapWithEC``
``compose`` works just like it does for functions.
``wrap`` is a compose that allows you to also change the ``ContentType`` that the marshaller marshals to.
The ``...WithEC`` variants allow you to receive an ``ExecutionContext`` internally if you need one, without having to
depend on one being available implicitly at the usage site.
Using Marshallers
-----------------
In many places throughput Akka HTTP marshallers are used implicitly, e.g. when you define how to :ref:`-complete-` a
request using the :ref:`Routing DSL <http-high-level-server-side-api>`.
However, you can also use the marshalling infrastructure directly if you wish, which can be useful for example in tests.
The best entry point for this is the ``akka.http.scaladsl.marshalling.Marshal`` object, which you can use like this:
.. TODO rewrite for Java
.. .. includecode2:: ../../code/docs/http/scaladsl/MarshalSpec.scala
:snippet: use marshal