=docs #18012 complete remaining TODO sections in scala HTTP docs

This commit is contained in:
Mathias 2015-07-17 16:18:18 +02:00
parent cf11eab9ae
commit 1441f201b1
19 changed files with 519 additions and 51 deletions

View file

@ -68,4 +68,16 @@ However, akka-stream should soon provide such a feature.
Stand-Alone HTTP Layer Usage
----------------------------
// TODO
Due to its Reactive-Stream-based nature the Akka HTTP layer is fully detachable from the underlying TCP
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
(e.g by replaying network traffic).
On the client-side the stand-alone HTTP layer forms a ``BidiStage`` that is defined like this:
.. includecode2:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala
:snippet: client-layer
You create an instance of ``Http.ClientLayer`` by calling one of the two overloads of the ``Http().clientLayer`` method,
which also allows for varying degrees of configuration.

View file

@ -1,4 +1,16 @@
Encoding / Decoding
===================
...
The `HTTP spec`_ defines a ``Content-Encoding`` header, which signifies whether the entity body of an HTTP message is
"encoded" and, if so, by which algorithm. The only commonly used content encodings are compression algorithms.
Currently Akka HTTP supports the compression and decompression of HTTP requests and responses with the ``gzip`` or
``deflate`` encodings.
The core logic for this lives in the `akka.http.scaladsl.coding`_ package.
The support is not enabled automatically, but must be explicitly requested.
For enabling message encoding/decoding with :ref:`Routing DSL <http-high-level-server-side-api>` see the :ref:`CodingDirectives`.
.. _HTTP spec: http://tools.ietf.org/html/rfc7231#section-3.1.2.1
.. _akka.http.scaladsl.coding: https://github.com/akka/akka/tree/release-2.3-dev/akka-http/src/main/scala/akka/http/scaladsl/coding

View file

@ -1,4 +1,32 @@
JSON Support
============
...
Akka HTTP's :ref:`marshalling <http-marshalling-scala>` and :ref:`unmarshalling <http-unmarshalling-scala>`
infrastructure makes it rather easy to seamlessly support specific wire representations of your data objects, like JSON,
XML or even binary encodings.
For JSON Akka HTTP currently provides support for `spray-json`_ right out of the box through it's
``akka-http-spray-json`` module.
spray-json Support
------------------
The SprayJsonSupport_ trait provides a ``FromEntityUnmarshaller[T]`` and ``ToEntityMarshaller[T]`` for every type ``T``
that an implicit ``spray.json.RootJsonReader`` and/or ``spray.json.RootJsonWriter`` (respectively) is available for.
This is how you enable automatic support for (un)marshalling from and to JSON with `spray-json`_:
1. Add a library dependency onto ``"com.typesafe.akka" %% "akka-http-spray-json-experimental" % "1.x"``.
2. ``import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._`` or mix in the
``akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport`` trait.
3. Provide a ``RootJsonFormat[T]`` for your type and bring it into scope.
Check out the `spray-json`_ documentation for more info on how to do this.
Once you have done this (un)marshalling between JSON and your type ``T`` should work nicely and transparently.
.. _spray-json: https://github.com/spray/spray-json
.. _SprayJsonSupport: @github@/akka-http-marshallers-scala/akka-http-spray-json/src/main/scala/akka/http/scaladsl/marshallers/sprayjson/SprayJsonSupport.scala

View file

@ -3,4 +3,162 @@
Marshalling
===========
...
"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 you own marshallers you won't have to "manually" implement the ``Marshaller`` trait directly.
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:
.. includecode2:: ../../code/docs/http/scaladsl/MarshalSpec.scala
:snippet: use marshal

View file

@ -3,4 +3,117 @@
Unmarshalling
=============
...
"Unmarshalling" is the process of converting some kind of a lower-level representation, often a "wire format", into a
higher-level (object) structure. Other popular names for it are "Deserialization" or "Unpickling".
In Akka HTTP "Unmarshalling" means the conversion of a lower-level source object, e.g. a ``MessageEntity``
(which forms the "entity body" of an HTTP request or response) or a full ``HttpRequest`` or ``HttpResponse``,
into an instance of type ``T``.
Basic Design
------------
Unmarshalling of instances of type ``A`` into instances of type ``B`` is performed by an ``Unmarshaller[A, B]``.
Akka HTTP also predefines a number of helpful aliases for the types of unmarshallers that you'll likely work with most:
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/unmarshalling/package.scala
:snippet: unmarshaller-aliases
At its core an ``Unmarshaller[A, B]`` is very similar to a function ``A => Future[B]`` and as such quite a bit simpler
than its :ref:`marshalling <http-marshalling-scala>` counterpart. The process of unmarshalling does not have to support
content negotiation which saves two additional layers of indirection that are required on the marshalling side.
Predefined Unmarshallers
------------------------
Akka HTTP already predefines a number of marshallers for the most common types.
Specifically these are:
- PredefinedFromStringUnmarshallers_
- ``Byte``
- ``Short``
- ``Int``
- ``Long``
- ``Float``
- ``Double``
- ``Boolean``
- PredefinedFromEntityUnmarshallers_
- ``Array[Byte]``
- ``ByteString``
- ``Array[Char]``
- ``String``
- ``akka.http.scaladsl.model.FormData``
- GenericUnmarshallers_
- ``Unmarshaller[T, T]`` (identity unmarshaller)
- ``Unmarshaller[Option[A], B]``, if an ``Unmarshaller[A, B]`` is available
- ``Unmarshaller[A, Option[B]]``, if an ``Unmarshaller[A, B]`` is available
.. _PredefinedFromStringUnmarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/unmarshalling/PredefinedFromStringUnmarshallers.scala
.. _PredefinedFromEntityUnmarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/unmarshalling/PredefinedFromEntityUnmarshallers.scala
.. _GenericUnmarshallers: @github@/akka-http/src/main/scala/akka/http/scaladsl/unmarshalling/GenericUnmarshallers.scala
Implicit Resolution
-------------------
The unmarshalling infrastructure of Akka HTTP relies on a type-class based approach, which means that ``Unmarshaller``
instances from a certain type ``A`` to a certain type ``B`` have to be available implicitly.
The implicits for most of the predefined unmarshallers in Akka HTTP are provided through the companion object of the
``Unmarshaller`` 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 Unmarshallers
--------------------
Akka HTTP gives you a few convenience tools for constructing unmarshallers for your own types.
Usually you won't have to "manually" implement the ``Unmarshaller`` trait directly.
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/unmarshalling/Unmarshaller.scala
:snippet: unmarshaller-creation
Deriving Unmarshallers
----------------------
Sometimes you can save yourself some work by reusing existing unmarshallers for your custom ones.
The idea is to "wrap" an existing unmarshaller with some logic to "re-target" it to your type.
Usually what you want to do is to transform the output of some existing unmarshaller and convert it to your type.
For this type of unmarshaller transformation Akka HTTP defines these methods:
- ``baseUnmarshaller.transform``
- ``baseUnmarshaller.map``
- ``baseUnmarshaller.mapWithInput``
- ``baseUnmarshaller.flatMap``
- ``baseUnmarshaller.flatMapWithInput``
- ``baseUnmarshaller.recover``
- ``baseUnmarshaller.withDefaultValue``
- ``baseUnmarshaller.mapWithCharset`` (only available for FromEntityUnmarshallers)
- ``baseUnmarshaller.forContentTypes`` (only available for FromEntityUnmarshallers)
The method signatures should make their semantics relatively clear.
Using Unmarshallers
-------------------
In many places throughput Akka HTTP unmarshallers are used implicitly, e.g. when you want to access the :ref:`-entity-`
of a request using the :ref:`Routing DSL <http-high-level-server-side-api>`.
However, you can also use the unmarshalling infrastructure directly if you wish, which can be useful for example in tests.
The best entry point for this is the ``akka.http.scaladsl.unmarshalling.Unmarshal`` object, which you can use like this:
.. includecode2:: ../../code/docs/http/scaladsl/UnmarshalSpec.scala
:snippet: use unmarshal

View file

@ -1,4 +1,29 @@
XML Support
===========
...
Akka HTTP's :ref:`marshalling <http-marshalling-scala>` and :ref:`unmarshalling <http-unmarshalling-scala>`
infrastructure makes it rather easy to seamlessly support specific wire representations of your data objects, like JSON,
XML or even binary encodings.
For XML Akka HTTP currently provides support for `Scala XML`_ right out of the box through it's
``akka-http-xml`` module.
Scala XML Support
-----------------
The ScalaXmlSupport_ trait provides a ``FromEntityUnmarshaller[NodeSeq]`` and ``ToEntityMarshaller[NodeSeq]`` that
you can use directly or build upon.
This is how you enable support for (un)marshalling from and to JSON with `Scala XML`_ ``NodeSeq``:
1. Add a library dependency onto ``"com.typesafe.akka" %% "akka-http-xml-experimental" % "1.x"``.
2. ``import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._`` or mix in the
``akka.http.scaladsl.marshallers.xml.ScalaXmlSupport`` trait.
Once you have done this (un)marshalling between XML and ``NodeSeq`` instances should work nicely and transparently.
.. _Scala XML: https://github.com/scala/scala-xml
.. _ScalaXmlSupport: @github@/akka-http-marshallers-scala/akka-http-xml/src/main/scala/akka/http/scaladsl/marshallers/xml/ScalaXmlSupport.scala

View file

@ -154,4 +154,16 @@ If defined encryption is enabled on all accepted connections. Otherwise it is di
Stand-Alone HTTP Layer Usage
----------------------------
// TODO
Due to its Reactive-Stream-based nature the Akka HTTP layer is fully detachable from the underlying TCP
interface. While in most applications this "feature" will not be crucial it can be useful in certain cases to be able
to "run" the HTTP layer (and, potentially, higher-layers) against data that do not come from the network but rather
some other source. Potential scenarios where this might be useful include tests, debugging or low-level event-sourcing
(e.g by replaying network traffic).
On the server-side the stand-alone HTTP layer forms a ``BidiStage`` that is defined like this:
.. includecode2:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala
:snippet: server-layer
You create an instance of ``Http.ServerLayer`` by calling one of the two overloads of the ``Http().serverLayer`` method,
which also allows for varying degrees of configuration.

View file

@ -1,7 +1,7 @@
.. _-withMaterializer-:
withMaterializer
====================
================
...

View file

@ -26,7 +26,7 @@ other mechanism. After authentication the system believes that it knows who the
most cases, in order to be able to authorize a user (i.e. allow access to some part of the system) the users identity
must already have been established, i.e. he/she must have been authenticated. Without prior authentication the
authorization would have to be very crude, e.g. "allow access for *all* users" or "allow access for *noone*". Only after
authentication will it be possible to, e.g., "allow access to the statistics resource for _admins_, but not for regular
authentication will it be possible to, e.g., "allow access to the statistics resource for *admins*, but not for regular
*members*".
Authentication and authorization may happen at the same time, e.g. when everyone who can properly be authenticated is
@ -35,5 +35,17 @@ system might have one mechanism for authentication (e.g. establishing user ident
for authorization (e.g. a database lookup for retrieving user access rights).
// TODO: Explain the role of HTTP in this picture (as in, the methods listed here map to HTTP, but there is no general
purpose AAA solution provided here)
Authentication and Authorization in HTTP
----------------------------------------
HTTP provides a general framework for access control and authentication, via an extensible set of challenge-response
authentication schemes, which can be used by a server to challenge a client request and by a client to provide
authentication information. The general mechanism is defined in `RFC 7235`_.
The "HTTP Authentication Scheme Registry" defines the namespace for the authentication schemes in challenges and
credentials. You can see the currently registered schemes at http://www.iana.org/assignments/http-authschemes.
At this point Akka HTTP only implements the "'Basic' HTTP Authentication Scheme" whose most current specification can be
found here: https://datatracker.ietf.org/doc/draft-ietf-httpauth-basicauth-update/.
.. _RFC 7235: http://tools.ietf.org/html/rfc7235