pekko/akka-docs-dev/rst/java/http/routing-dsl/handlers.rst

105 lines
5.1 KiB
ReStructuredText
Raw Normal View History

2015-07-10 19:11:08 +02:00
.. _handlers-java:
Handlers
========
Handlers implement the actual application-defined logic for a certain trace in the routing tree. Most of the leaves of
the routing tree will be routes created from handlers. Creating a ``Route`` from a handler is achieved using the
``BasicDirectives.handleWith`` overloads. They come in several forms:
* with a single ``Handler`` argument and a variable number of ``RequestVal<?>`` (may be 0)
* with a number ``n`` of ``RequestVal<T1>`` arguments and a ``HandlerN<T1, .., TN>`` argument
* with a ``Class<?>`` and/or instance and a method name String argument and a variable number of ``RequestVal<?>`` (may be 0)
arguments
2015-07-10 19:11:08 +02:00
Simple Handler
--------------
In its simplest form a ``Handler`` is a SAM class that defines application behavior
by inspecting the ``RequestContext`` and returning a ``RouteResult``:
.. includecode:: /../../akka-http/src/main/scala/akka/http/javadsl/server/Handler.scala
:include: handler
Such a handler inspects the ``RequestContext`` it receives and uses the ``RequestContext``'s methods to
create a response:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: simple-handler
The handler can include any kind of logic but must return a ``RouteResult`` in the end which can only
be created by using one of the ``RequestContext`` methods.
A handler instance can be used once or several times as shown in the full example:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: simple-handler-example-full
Handlers and Request Values
---------------------------
In many cases, instead of manually inspecting the request, a handler will make use of :ref:`request-vals-java`
to extract details from the request. This is possible using one of the other ``handleWith`` overloads that bind
the values of one or more request values with a ``HandlerN`` instance to produce a ``Route``:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: handler2
The handler here implements multiplication of two integers. However, it doesn't need to specify where these
parameters come from. In ``handleWith``, as many request values of the matching type have to be specified as the
handler needs. This can be seen in the full example:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: handler2-example-full
Here, the handler is again being reused. First, in creating a route that expects URI parameters ``x`` and ``y``. This
route is then used in the route structure. And second, the handler is used with another set of ``RequestVal`` in the
route structure, this time representing segments from the URI path.
Handlers in Java 8
------------------
Handlers are in fact simply classes which extend ``akka.japi.function.FunctionN`` in order to make reasoning
about the number of handled arguments easier. For example, a :class:`Handler1[String]` is simply a
``Function2[RequestContext, String, RouteResult]``. You can think of handlers as hot-dogs, where each ``T``
type represents a sausage, put between the "buns" which are ``RequestContext`` and ``RouteResult``.
In Java 8 handlers can be provided as function literals or method references. The example from before then looks like this:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
:include: handler2-java8-example-full
.. note::
The reason the ``handleWith##`` methods include the number of handled values is because otherwise (if overloading would
be used, for all 22 methods) error messages generated by ``javac`` end up being very long and not readable, i.e.
if one type of a handler does not match the given values, *all* possible candidates would be printed in the error message
(22 of them), instead of just the one arity-matching method, pointing out that the type does not match.
We opted for better error messages as we feel this is more helpful when developing applications,
instead of having one overloaded method which looks nice when everything works, but procudes hard to read error
messages if something does not match up.
2015-07-10 19:11:08 +02:00
Providing Handlers by Reflection
--------------------------------
Using Java before Java 8, writing out handlers as (anonymous) classes can be unwieldy. Therefore, ``handleReflectively``
2015-07-10 19:11:08 +02:00
overloads are provided that allow writing handler as simple methods and specifying them by name:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: reflective
The complete calculator example can then be written like this:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java
2015-07-10 19:11:08 +02:00
:include: reflective-example-full
There are alternative overloads for ``handleReflectively`` that take a ``Class`` instead of an object instance to refer to
2015-07-10 19:11:08 +02:00
static methods. The referenced method must be publicly accessible.
Deferring Result Creation
-------------------------
TODO