=doc document java-side handlers

This commit is contained in:
Johannes Rudolph 2015-07-10 19:11:08 +02:00
parent f9b8125333
commit 6d80945be2
10 changed files with 332 additions and 1 deletions

View file

@ -0,0 +1,157 @@
/*
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.http.javadsl;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.server.*;
import akka.http.javadsl.server.values.Parameters;
import akka.http.javadsl.server.values.PathMatchers;
import akka.http.javadsl.testkit.JUnitRouteTest;
import akka.http.javadsl.testkit.TestRoute;
import org.junit.Test;
public class HandlerExampleSpec extends JUnitRouteTest {
@Test
public void testSimpleHandler() {
//#simple-handler-example-full
class TestHandler extends akka.http.javadsl.server.AllDirectives {
//#simple-handler
Handler handler = new Handler() {
@Override
public RouteResult handle(RequestContext ctx) {
return ctx.complete("This was a " + ctx.request().method().value() +
" request to "+ctx.request().getUri());
}
};
//#simple-handler
Route createRoute() {
return route(
get(
handleWith(handler)
),
post(
path("abc").route(
handleWith(handler)
)
)
);
}
}
// actual testing code
TestRoute r = testRoute(new TestHandler().createRoute());
r.run(HttpRequest.GET("/test"))
.assertStatusCode(200)
.assertEntity("This was a GET request to /test");
r.run(HttpRequest.POST("/test"))
.assertStatusCode(404);
r.run(HttpRequest.POST("/abc"))
.assertStatusCode(200)
.assertEntity("This was a POST request to /abc");
//#simple-handler-example-full
}
@Test
public void testCalculator() {
//#handler2-example-full
class TestHandler extends akka.http.javadsl.server.AllDirectives {
RequestVal<Integer> xParam = Parameters.intValue("x");
RequestVal<Integer> yParam = Parameters.intValue("y");
RequestVal<Integer> xSegment = PathMatchers.integerNumber();
RequestVal<Integer> ySegment = PathMatchers.integerNumber();
//#handler2
Handler2<Integer, Integer> multiply =
new Handler2<Integer, Integer>() {
@Override
public RouteResult handle(RequestContext ctx, Integer x, Integer y) {
int result = x * y;
return ctx.complete("x * y = " + result);
}
};
Route multiplyXAndYParam = handleWith(xParam, yParam, multiply);
//#handler2
Route createRoute() {
return route(
get(
pathPrefix("calculator").route(
path("multiply").route(
multiplyXAndYParam
),
path("path-multiply", xSegment, ySegment).route(
handleWith(xSegment, ySegment, multiply)
)
)
)
);
}
}
// actual testing code
TestRoute r = testRoute(new TestHandler().createRoute());
r.run(HttpRequest.GET("/calculator/multiply?x=12&y=42"))
.assertStatusCode(200)
.assertEntity("x * y = 504");
r.run(HttpRequest.GET("/calculator/path-multiply/23/5"))
.assertStatusCode(200)
.assertEntity("x * y = 115");
//#handler2-example-full
}
@Test
public void testCalculatorReflective() {
//#reflective-example-full
class TestHandler extends akka.http.javadsl.server.AllDirectives {
RequestVal<Integer> xParam = Parameters.intValue("x");
RequestVal<Integer> yParam = Parameters.intValue("y");
RequestVal<Integer> xSegment = PathMatchers.integerNumber();
RequestVal<Integer> ySegment = PathMatchers.integerNumber();
//#reflective
public RouteResult multiply(RequestContext ctx, Integer x, Integer y) {
int result = x * y;
return ctx.complete("x * y = " + result);
}
Route multiplyXAndYParam = handleWith(this, "multiply", xParam, yParam);
//#reflective
Route createRoute() {
return route(
get(
pathPrefix("calculator").route(
path("multiply").route(
multiplyXAndYParam
),
path("path-multiply", xSegment, ySegment).route(
handleWith(this, "multiply", xSegment, ySegment)
)
)
)
);
}
}
// actual testing code
TestRoute r = testRoute(new TestHandler().createRoute());
r.run(HttpRequest.GET("/calculator/multiply?x=12&y=42"))
.assertStatusCode(200)
.assertEntity("x * y = 504");
r.run(HttpRequest.GET("/calculator/path-multiply/23/5"))
.assertStatusCode(200)
.assertEntity("x * y = 115");
//#reflective-example-full
}
}

View file

@ -0,0 +1,88 @@
.. _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
* 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<?>``
arguments
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:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
: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:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
: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:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
: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:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
: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
------------------
In Java 8 handlers can be provided as function literals. The example from before then looks like this:
.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleSpec.java
:include: handler2-example-full
Providing Handlers by Reflection
--------------------------------
Using Java before Java 8, writing out handlers as (anonymous) classes can be unwieldy. Therefore, ``handleWith``
overloads are provided that allow writing handler as simple methods and specifying them by name:
.. includecode:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
:include: reflective
The complete calculator example can then be written like this:
.. includecode:: ../../code/docs/http/javadsl/HandlerExampleSpec.java
:include: reflective-example-full
There are alternative overloads for ``handleWith`` that take a ``Class`` instead of an object instance to refer to
static methods. The referenced method must be publicly accessible.
Deferring Result Creation
-------------------------
TODO

View file

@ -12,3 +12,6 @@ High-level Server-Side API
routes
directives/index
request-vals/index
handlers
path-matchers
marshalling

View file

@ -0,0 +1,6 @@
.. _marshalling-java:
Marshalling & Unmarshalling
===========================
TODO

View file

@ -56,6 +56,12 @@ fields, details of the request like headers, URI, the entity, or authentication
Read more about :ref:`request-vals-java`.
The actual application-defined processing of a request is defined with a ``Handler`` instance or by specifying
a handling method with reflection. A handler can receive the value of any request values and is converted into
a ``Route`` by using one of the ``BasicDirectives.handleWith`` directives.
Read more about :ref:`handlers-java`.
Requests or responses often contain data that needs to be interpreted or rendered in some way.
Akka-http provides the abstraction of ``Marshaller`` and ``Unmarshaller`` that define how domain model objects map
to HTTP entities.

View file

@ -0,0 +1,6 @@
.. _pathmatcher-dsl-java:
The PathMatcher DSL
===================
TODO