=htp move docs and create TOC structure

This commit is contained in:
Roland Kuhn 2014-12-20 14:27:48 +01:00
parent 2d140eee30
commit dc0c827ecf
12 changed files with 66 additions and 49 deletions

View file

@ -0,0 +1,4 @@
Client API
==========
(todo)

View file

@ -0,0 +1,6 @@
HTTPS
=====
Is not yet supported.
(todo)

View file

@ -0,0 +1,12 @@
.. _http-client-server-scala:
HTTP Client & Server
====================
.. toctree::
:maxdepth: 2
model
client
server
https

View file

@ -0,0 +1,18 @@
.. _http-routing-index-scala:
HTTP Routing
============
.. toctree::
:maxdepth: 2
quick-start
routing
directives
rejections
exception-handling
path-matchers
marshalling
directives/alphabetically
directives/by-trait

View file

@ -0,0 +1,8 @@
.. _http-testkit-scala:
HTTP TestKit
============
.. note::
This part of the documentation has not yet been written, please stay tuned for updates.

View file

@ -1,17 +1,28 @@
High-level HTTP API
===================
.. _http-scala:
Akka HTTP
=========
The purpose of the Akka HTTP layer is to expose Actors to the web via HTTP and
to enable them to consume HTTP services as a client. It is not an HTTP
framework, it is an Actor-based toolkit for interacting with web services and
clients. This toolkit is structured into several layers:
* ``akka-http-core``: A complete implementation of the HTTP standard, both as
client and server.
* ``akka-http``: A convenient and powerful routing DSL for expressing web
services.
* ``akka-http-testkit``: A test harness and set of utilities for verifying
your web service implementations.
Additionally there are several integration modules with bindings for different
serialization and deserialization schemes for HTTP entities.
.. toctree::
:maxdepth: 2
quick-start
routing
directives
rejections
exception-handling
path-matchers
marshalling
directives/alphabetically
directives/by-trait
index-client-server
index-routing
index-testkit

View file

@ -0,0 +1,156 @@
.. _http-model-scala:
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``.
HttpEntity.IndefiniteLength
A streaming entity of unspecified length that can be used as a ``BodyPart`` entity.
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 for a response as an alternative to Chunked e.g. if chunked transfer encoding isn't supported
by a client.
- Use IndefiniteLength instead of CloseDelimited in a BodyPart.
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.

View file

@ -0,0 +1,157 @@
.. _http-core-server-scala:
Server API
==========
The Akka HTTP server is an embedded, stream-based, fully asynchronous, low-overhead
HTTP/1.1 server implemented on top of `Akka Streams`_. (todo: fix link)
It sports the following features:
- Full support for `HTTP persistent connections`_
- Full support for `HTTP pipelining`_
- Full support for asynchronous HTTP streaming including "chunked" transfer encoding accessible through an idiomatic
reactive streams API
- Optional SSL/TLS encryption
.. _HTTP persistent connections: http://en.wikipedia.org/wiki/HTTP_persistent_connection
.. _HTTP pipelining: http://en.wikipedia.org/wiki/HTTP_pipelining
.. _Akka streams: http://akka.io/docs/
Design Philosophy
-----------------
Akka HTTP server is scoped with a clear focus on the essential functionality of an HTTP/1.1 server:
- Connection management
- Parsing messages and headers
- Timeout management (for requests and connections)
- Response ordering (for transparent pipelining support)
All non-core features of typical HTTP servers (like request routing, file serving, compression, etc.) are left to
the next-higher layer in the application stack, they are not implemented by the HTTP server itself.
Apart from general focus this design keeps the server small and light-weight as well as easy to understand and
maintain.
Basic Architecture
------------------
Akka HTTP server is implemented on top of Akka streams and makes heavy use of them - in its
implementation and also on all levels of its API.
On the connection level Akka HTTP supports basically the same interface as Akka streams IO: A socket binding is
represented as a stream of incoming connections. The application needs to provide a ``Flow[HttpRequest, HttpResponse]``
to "translate" requests into responses.
Streaming is also supported for single message entities itself. Particular kinds of ``HttpEntity``
subclasses provide support for fixed or streamed message entities.
Starting and Stopping
---------------------
An Akka HTTP server is bound by invoking the ``bind`` method of the `akka.http.Http`_ extension:
.. includecode:: ../code/docs/http/HttpServerExampleSpec.scala
:include: bind-example
Arguments to the ``Http.bind`` method specify the interface and port to bind to and register interest in handling incoming
HTTP connections. Additionally, the method also allows you to define socket options as well as a larger number
of settings for configuring the server according to your needs.
The result of the ``bind`` method is a ``Http.ServerBinding`` which is immediately returned. The ``ServerBinding.connections``
returns a ``Source[IncomingConnection]`` which is used to handle incoming connections. The actual binding is only done when this
source is materialized as part of a bigger processing pipeline. In case the bind fails (e.g. because the port is already
busy) the error will be reported by flagging an error on the ``IncomingConnection`` stream.
After materialization ``ServerBinding.localAddress`` returns the actual local address of the bound socket.
Connections are handled by materializing a pipeline which uses the ``Source[IncomingConnection]`` returned by
``ServerBinding.connections``. The binding is released and the underlying listening socket is closed when all
subscribers of the ``connections`` source have cancelled their subscription.
(todo: explain even lower level serverFlowToTransport API)
.. _akka.http.Http: @github@/akka-http-core/src/main/scala/akka/http/Http.scala
Request-Response Cycle
----------------------
When a new connection has been accepted it will be published by by the ``ServerBinding.connections`` source as an
``Http.IncomingConnection`` which consists of the remote address, and methods to provide a ``Flow[HttpRequest, HttpResponse]``
to handle requests coming in over this connection.
Requests are handled by calling one of the ``IncomingConnection.handleWithX`` methods with a handler, which can either be
- a ``Flow[HttpRequest, HttpResponse]`` for ``handleWith``,
- a function ``HttpRequest => HttpResponse`` for ``handleWithSyncHandler``,
- or a function ``HttpRequest => Future[HttpResponse]`` for ``handleWithAsyncHandler``.
.. includecode:: ../code/docs/http/HttpServerExampleSpec.scala
:include: full-server-example
In this case, a request is handled by transforming the request stream with a function ``HttpRequest => HttpResponse``
using ``handleWithSyncHandler`` (or equivalently, Akka stream's ``map`` operator). Depending on the use case, arbitrary
other ways of connecting are conceivable using Akka stream's combinators.
If the application provides a ``Flow``, it is also the responsibility of the application to generate exactly one response
for every request and that the ordering of responses matches the ordering of the associated requests (which is relevant
if HTTP pipelining is enabled where processing of multiple incoming requests may overlap). Using ``handleWithSyncHandler``
or ``handleWithAsyncHandler`` or, instead, if using stream operators like ``map`` or ``mapFuture`` this requirement
will automatically be fulfilled.
Streaming request/response entities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Streaming of HTTP message entities is supported through subclasses of ``HttpEntity``. You need to be able to deal
with streamed entities when receiving a request as well as when constructing responses. See :ref:`HttpEntity` for
a description of the alternatives.
(todo): Link to :ref:`http-routing-scala` for (un-)marshalling facilities.
Closing a connection
~~~~~~~~~~~~~~~~~~~~
The HTTP connection will be closed when the handling ``Flow`` cancel its upstream subscription or the peer closes the
connection.
You can also use the value of the ``Connection`` header of a response as described below to give a hint to the
implementation to close the connection after the completion of the response.
HTTP Headers
------------
When the Akka HTTP server receives an HTTP request it tries to parse all its headers into their respective
model classes. No matter whether this succeeds or not, the connection actor will always pass on all
received headers to the application. Unknown headers as well as ones with invalid syntax (according to the header
parser) will be made available as ``RawHeader`` instances. For the ones exhibiting parsing errors a warning message is
logged depending on the value of the ``illegal-header-warnings`` config setting.
Some common headers are treated specially in the model and in the implementation and should not occur in the ``headers``
field of an HTTP message:
- ``Content-Type``: Use the ``contentType`` field of the ``HttpEntity`` subclasses to set or determine the content-type
on an entity.
- ``Transfer-Encoding``: The ``Transfer-Encoding`` is represented by subclasses of ``HttpEntity``.
- ``Content-Length``: The ``Content-Length`` header is represented implicitly by the choice of an ``HttpEntity`` subclass:
A Strict entity determines the Content-Length by the length of the data provided. A Default entity has an explicit
``contentLength`` field which specifies the amount of data the streaming producer will produce. Chunked and CloseDelimited
entities don't need to define a length.
- ``Server``: The ``Server`` header is usually added automatically and it's value can be configured. An application can
decide to provide a custom ``Server`` header by including an explicit instance in the response.
- ``Date``: The ``Date`` header is added automatically and can be overridden by supplying it manually.
- ``Connection``: When sending out responses the connection actor watches for a ``Connection`` header set by the
application and acts accordingly, i.e. you can force the connection actor to close the connection after having sent
the response by including a ``Connection("close")`` header. To unconditionally force a connection keep-alive you can
explicitly set a ``Connection("Keep-Alive")`` header. If you don't set an explicit ``Connection`` header the
connection actor will keep the connection alive if the client supports this (i.e. it either sent a
``Connection: Keep-Alive`` header or advertised HTTP/1.1 capabilities without sending a ``Connection: close`` header).
SSL Support
-----------
(todo)