pekko/akka-docs-dev/rst/scala/http-model.rst
2014-06-16 23:09:51 +02:00

151 lines
6.5 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.. _http-model-scala:
HTTP Model
==========
The akka HTTP model contains a mostly immutable, case-class based model of the major HTTP data structures,
like HTTP requests, responses and common headers. It also includes a parser for the latter, which is able to construct
the more structured header models from raw unstructured header name/value pairs.
Overview
--------
Since akka-http-core provides the central HTTP data structures you will find the following import in quite a
few places around the code base (and probably your own code as well):
.. includecode:: code/docs/http/ModelSpec.scala
:include: import-model
This brings in scope all of the relevant things that are defined here and that youll want to work with, mainly:
- ``HttpRequest`` and ``HttpResponse``, the central message model
- ``headers``, the package containing all the predefined HTTP header models and supporting types
- Supporting types like ``Uri``, ``HttpMethods``, ``MediaTypes``, ``StatusCodes``, etc.
A common pattern is that the model of a certain entity is represented by an immutable type (class or trait),
while the actual instances of the entity defined by the HTTP spec live in an accompanying object carrying the name of
the type plus a trailing plural 's'.
For example:
- Defined HttpMethod instances live in the HttpMethods object.
- Defined HttpCharset instances live in the HttpCharsets object.
- Defined HttpEncoding instances live in the HttpEncodings object.
- Defined HttpProtocol instances live in the HttpProtocols object.
- Defined MediaType instances live in the MediaTypes object.
- Defined StatusCode instances live in the StatusCodes object.
HttpRequest / HttpResponse
--------------------------
``HttpRequest`` and ``HttpResponse`` are the basic case classes representing HTTP messages.
An ``HttpRequest`` consists of
- method (GET, POST, etc.)
- URI
- protocol
- headers
- entity (body data)
Here are some examples how to construct an ``HttpRequest``:
.. includecode:: code/docs/http/ModelSpec.scala
:include: construct-request
All parameters of ``HttpRequest`` have default values set, so e.g. ``headers`` don't need to be specified
if there are none. Many of the parameters types (like ``HttpEntity`` and ``Uri``) define implicit conversions
for common use cases to simplify the creation of request and response instances.
An ``HttpResponse`` consists of
- status code
- protocol
- headers
- entity
Here are some examples how to construct an ``HttpResponse``:
.. includecode:: code/docs/http/ModelSpec.scala
:include: construct-response
Aside from the simple ``HttpEntity`` constructors to create an entity from a fixed ``ByteString`` shown here,
subclasses of ``HttpEntity`` allow data to be specified as a stream of data which is explained in the next section.
.. _HttpEntity:
HttpEntity
----------
An ``HttpEntity`` carries the content of a request together with its content-type which is needed to interpret the raw
byte data.
Akka HTTP provides several kinds of entities to support static and streaming data for the different kinds of ways
to transport streaming data with HTTP. There are four subtypes of HttpEntity:
HttpEntity.Strict
An entity which wraps a static ``ByteString``. It represents a standard, non-chunked HTTP message with ``Content-Length``
set.
HttpEntity.Default
A streaming entity which needs a predefined length and a ``Producer[ByteString]`` to produce the body data of
the message. It represents a standard, non-chunked HTTP message with ``Content-Length`` set. It is an error if the
provided ``Producer[ByteString]`` doesn't produce exactly as many bytes as specified. On the wire, a Strict entity
and a Default entity cannot be distinguished. However, they offer a valuable alternative in the API to distinguish
between strict and streamed data.
HttpEntity.Chunked
A streaming entity of unspecified length that uses `Chunked Transfer Coding`_ for transmitting data. Data is
represented by a ``Producer[ChunkStreamPart]``. A ``ChunkStreamPart`` is either a non-empty ``Chunk`` or a ``LastChunk``
containing optional trailer headers. The stream must consist of 0..n ``Chunked`` parts and can be terminated by an
optional ``LastChunk`` part (which carries optional trailer headers).
HttpEntity.CloseDelimited
A streaming entity of unspecified length that is delimited by closing the connection ("Connection: close"). Note,
that this entity type can only be used in an ``HttpResponse``.
Entity types ``Strict``, ``Default``, and ``Chunked`` are a subtype of ``HttpEntity.Regular`` which allows to use them for
requests and responses. In contrast, ``HttpEntity.CloseDelimited`` can only be used for responses.
Streaming entity types (i.e. all but ``Strict``) cannot be shared or serialized. To create a strict, sharable copy of an
entity or message use ``HttpEntity.toStrict`` or ``HttpMessage.toStrict`` which returns a Future of the object with the
body data collected into a ``ByteString``.
.. _Chunked Transfer Coding: http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26#section-4.1
The ``HttpEntity`` companion object contains several helper constructors to create entities from common types easily.
You can pattern match over the subtypes of ``HttpEntity`` if you want to provide special handling for each of the
subtypes. However, in many cases a recipient of an `HttpEntity` doesn't care about of which subtype an entity is
(and how data is transported exactly on the HTTP layer). Therefore, a general ``HttpEntity.dataBytes`` is provided
which allows access to the data of an entity regardless of its concrete subtype.
.. note::
When to use which subtype?
- Use Strict if the amount of data is small and it is already in the heap (or even available as a ``ByteString``)
- Use Default if the data is generated by a streaming data source and the size of the data is fixed
- Use Chunked to support a data stream of unknown length
- Use CloseDelimited as an alternative to Chunked e.g. if chunked transfer encoding isn't supported by a peer.
Header model
------------
Akka HTTP contains a rich model of the common HTTP headers. Parsing and rendering is done automatically so that
applications don't need to care for the actual syntax of headers. Headers not modelled explicitly are represented
as a ``RawHeader``.
See these examples of how to deal with headers:
.. includecode:: code/docs/http/ModelSpec.scala
:include: headers
Parsing / Rendering
-------------------
Parsing and rendering of HTTP data structures is heavily optimized and for most types there's currently no public API
provided to parse (or render to) Strings or byte arrays.