diff --git a/akka-docs-dev/rst/java/code/docs/http/javadsl/HighLevelServerExample.java b/akka-docs-dev/rst/java/code/docs/http/javadsl/HighLevelServerExample.java index 4fd0e09052..a72d99a21d 100644 --- a/akka-docs-dev/rst/java/code/docs/http/javadsl/HighLevelServerExample.java +++ b/akka-docs-dev/rst/java/code/docs/http/javadsl/HighLevelServerExample.java @@ -32,12 +32,12 @@ public class HighLevelServerExample extends HttpApp { public Route createRoute() { // This handler generates responses to `/hello?name=XXX` requests Route helloRoute = - handleWith(name, + handleWith1(name, // in Java 8 the following becomes simply // (ctx, name) -> ctx.complete("Hello " + name + "!") new Handler1() { @Override - public RouteResult handle(RequestContext ctx, String name) { + public RouteResult apply(RequestContext ctx, String name) { return ctx.complete("Hello " + name + "!"); } }); diff --git a/akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleSpec.java b/akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleDocTest.java similarity index 99% rename from akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleSpec.java rename to akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleDocTest.java index ff0731baaa..2aa115fdc2 100644 --- a/akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleSpec.java +++ b/akka-docs-dev/rst/java/code/docs/http/javadsl/HttpServerExampleDocTest.java @@ -28,7 +28,7 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.concurrent.TimeUnit; -public class HttpServerExampleSpec { +public class HttpServerExampleDocTest { public static void bindingExample() { //#binding-example ActorSystem system = ActorSystem.create(); diff --git a/akka-docs-dev/rst/java/code/docs/http/javadsl/PathDirectiveExampleTest.java b/akka-docs-dev/rst/java/code/docs/http/javadsl/PathDirectiveExampleTest.java index de41f7ace4..0f1277d879 100644 --- a/akka-docs-dev/rst/java/code/docs/http/javadsl/PathDirectiveExampleTest.java +++ b/akka-docs-dev/rst/java/code/docs/http/javadsl/PathDirectiveExampleTest.java @@ -44,7 +44,7 @@ public class PathDirectiveExampleTest extends JUnitRouteTest { Handler1 completeWithUserId = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, Integer userId) { + public RouteResult apply(RequestContext ctx, Integer userId) { return ctx.complete("Hello user " + userId); } }; diff --git a/akka-docs-dev/rst/java/http/routing-dsl/handlers.rst b/akka-docs-dev/rst/java/http/routing-dsl/handlers.rst index 205199db52..885c306b15 100644 --- a/akka-docs-dev/rst/java/http/routing-dsl/handlers.rst +++ b/akka-docs-dev/rst/java/http/routing-dsl/handlers.rst @@ -7,10 +7,10 @@ Handlers implement the actual application-defined logic for a certain trace in t 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`` arguments and a ``HandlerN`` argument - * with a ``Class`` and/or instance and a method name String argument and a variable number of ``RequestVal`` - arguments +* with a single ``Handler`` argument and a variable number of ``RequestVal`` (may be 0) +* with a number ``n`` of ``RequestVal`` arguments and a ``HandlerN`` argument +* with a ``Class`` and/or instance and a method name String argument and a variable number of ``RequestVal`` (may be 0) + arguments Simple Handler -------------- @@ -24,7 +24,7 @@ by inspecting the ``RequestContext`` and returning a ``RouteResult``: 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 +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java :include: simple-handler The handler can include any kind of logic but must return a ``RouteResult`` in the end which can only @@ -32,7 +32,7 @@ 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 +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java :include: simple-handler-example-full Handlers and Request Values @@ -42,14 +42,14 @@ In many cases, instead of manually inspecting the request, a handler will make u 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 +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.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 +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.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 @@ -59,27 +59,44 @@ 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 previous example can then be written like this: +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. -.. 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`` +Using Java before Java 8, writing out handlers as (anonymous) classes can be unwieldy. Therefore, ``handleReflectively`` overloads are provided that allow writing handler as simple methods and specifying them by name: -.. includecode:: ../../code/docs/http/javadsl/HandlerExampleSpec.java +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java :include: reflective The complete calculator example can then be written like this: -.. includecode:: ../../code/docs/http/javadsl/HandlerExampleSpec.java +.. includecode:: /../../akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java :include: reflective-example-full -There are alternative overloads for ``handleWith`` that take a ``Class`` instead of an object instance to refer to +There are alternative overloads for ``handleReflectively`` that take a ``Class`` instead of an object instance to refer to static methods. The referenced method must be publicly accessible. Deferring Result Creation diff --git a/akka-docs-dev/rst/java/http/routing-dsl/overview.rst b/akka-docs-dev/rst/java/http/routing-dsl/overview.rst index 3828ad8a42..58ae27999d 100644 --- a/akka-docs-dev/rst/java/http/routing-dsl/overview.rst +++ b/akka-docs-dev/rst/java/http/routing-dsl/overview.rst @@ -7,7 +7,7 @@ The Akka HTTP :ref:`http-low-level-server-side-api-java` provides a ``Flow``- or an application to respond to incoming HTTP requests by simply mapping requests to responses (excerpt from :ref:`Low-level server side example `): -.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleSpec.java +.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleDocTest.java :include: request-handler While it'd be perfectly possible to define a complete REST API service purely by inspecting the incoming diff --git a/akka-docs-dev/rst/java/http/server-side/low-level-server-side-api.rst b/akka-docs-dev/rst/java/http/server-side/low-level-server-side-api.rst index c77bab6378..0be786d295 100644 --- a/akka-docs-dev/rst/java/http/server-side/low-level-server-side-api.rst +++ b/akka-docs-dev/rst/java/http/server-side/low-level-server-side-api.rst @@ -62,7 +62,7 @@ Starting and Stopping On the most basic level an Akka HTTP server is bound by invoking the ``bind`` method of the `akka.http.javadsl.Http`_ extension: -.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleSpec.java +.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleDocTest.java :include: binding-example Arguments to the ``Http().bind`` method specify the interface and port to bind to and register interest in handling @@ -99,7 +99,7 @@ Requests are handled by calling one of the ``handleWithXXX`` methods with a hand Here is a complete example: -.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleSpec.java +.. includecode:: ../../code/docs/http/javadsl/HttpServerExampleDocTest.java :include: full-server-example In this example, a request is handled by transforming the request stream with a function ``Function`` diff --git a/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala b/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala index 8f5ff87990..12cc38d616 100644 --- a/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala +++ b/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala @@ -7,25 +7,27 @@ package akka.http.scaladsl import java.net.InetSocketAddress import java.util.concurrent.ConcurrentHashMap import java.util.{ Collection ⇒ JCollection } -import javax.net.ssl.{ SSLParameters, SSLContext } -import com.typesafe.config.Config -import scala.util.Try -import scala.util.control.NonFatal -import scala.collection.{ JavaConverters, immutable } -import scala.concurrent.{ ExecutionContext, Promise, Future } -import akka.japi +import javax.net.ssl.{ SSLContext, SSLParameters } + +import akka.actor._ import akka.event.LoggingAdapter +import akka.http._ +import akka.http.impl.engine.client._ +import akka.http.impl.engine.server._ +import akka.http.impl.util.StreamUtils +import akka.http.scaladsl.model._ +import akka.http.scaladsl.model.headers.Host +import akka.http.scaladsl.util.FastFuture +import akka.japi import akka.stream.Materializer import akka.stream.io._ import akka.stream.scaladsl._ -import akka.http.impl.util.StreamUtils -import akka.http.impl.engine.client._ -import akka.http.impl.engine.server._ -import akka.http.scaladsl.util.FastFuture -import akka.http.scaladsl.model.headers.Host -import akka.http.scaladsl.model._ -import akka.http._ -import akka.actor._ +import com.typesafe.config.Config + +import scala.collection.immutable +import scala.concurrent.{ ExecutionContext, Future, Promise } +import scala.util.Try +import scala.util.control.NonFatal class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.Extension { @@ -397,8 +399,9 @@ class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.E * method call the respective connection pools will be restarted and not contribute to the returned future. */ def shutdownAllConnectionPools(): Future[Unit] = { - import scala.collection.JavaConverters._ import system.dispatcher + + import scala.collection.JavaConverters._ val gateways = hostPoolCache.values().asScala system.log.info("Initiating orderly shutdown of all active host connections pools...") Future.sequence(gateways.map(_.flatMap(_.shutdown()))).map(_ ⇒ ()) @@ -575,7 +578,7 @@ object Http extends ExtensionId[HttpExt] with ExtensionIdProvider { new HttpExt(system.settings.config getConfig "akka.http")(system) } -import JavaConverters._ +import scala.collection.JavaConverters._ //# https-context-impl case class HttpsContext(sslContext: SSLContext, diff --git a/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/JUnitRouteTest.scala b/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/JUnitRouteTest.scala index b71ac71959..039d47ee7b 100644 --- a/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/JUnitRouteTest.scala +++ b/akka-http-testkit/src/main/scala/akka/http/javadsl/testkit/JUnitRouteTest.scala @@ -4,14 +4,14 @@ package akka.http.javadsl.testkit -import akka.http.javadsl.server._ -import Directives._ -import org.junit.rules.ExternalResource -import org.junit.{ Rule, Assert } -import scala.concurrent.duration._ import akka.actor.ActorSystem -import akka.stream.ActorMaterializer +import akka.http.javadsl.server._ import akka.http.scaladsl.model.HttpResponse +import akka.stream.ActorMaterializer +import org.junit.rules.ExternalResource +import org.junit.{ Assert, Rule } + +import scala.concurrent.duration._ /** * A RouteTest that uses JUnit assertions. @@ -39,8 +39,8 @@ abstract class JUnitRouteTestBase extends RouteTest { } protected def completeWithValueToString[T](value: RequestVal[T]): Route = - handleWith(value, new Handler1[T] { - def handle(ctx: RequestContext, t: T): RouteResult = ctx.complete(t.toString) + handleWith1(value, new Handler1[T] { + def apply(ctx: RequestContext, t: T): RouteResult = ctx.complete(t.toString) }) } abstract class JUnitRouteTest extends JUnitRouteTestBase { diff --git a/akka-http-tests-java8/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp8.java b/akka-http-tests-java8/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp8.java index d223cadc24..3be7bfea36 100644 --- a/akka-http-tests-java8/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp8.java +++ b/akka-http-tests-java8/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp8.java @@ -34,14 +34,14 @@ public class SimpleServerApp8 extends HttpApp { } public void test() { - handleWith(xSegment, ySegment, SimpleServerApp8::multiply); + handleWith2(xSegment, ySegment, SimpleServerApp8::multiply); } @Override public Route createRoute() { Handler addHandler = new Handler() { @Override - public RouteResult handle(RequestContext ctx) { + public RouteResult apply(RequestContext ctx) { int xVal = x.get(ctx); int yVal = y.get(ctx); int result = xVal + yVal; @@ -49,7 +49,7 @@ public class SimpleServerApp8 extends HttpApp { } }; Handler2 subtractHandler = new Handler2() { - public RouteResult handle(RequestContext ctx, Integer xVal, Integer yVal) { + public RouteResult apply(RequestContext ctx, Integer xVal, Integer yVal) { int result = xVal - yVal; return ctx.complete(String.format("%d - %d = %d", xVal, yVal, result)); } @@ -63,25 +63,25 @@ public class SimpleServerApp8 extends HttpApp { ), // matches paths like this: /add?x=42&y=23 path("add").route( - handleWith(addHandler, x, y) + handleWith(addHandler) ), path("subtract").route( - handleWith(x, y, subtractHandler) + handleWith2(x, y, subtractHandler) ), path("divide").route( - handleWith(x, y, - (ctx, x, y) -> - ctx.complete(String.format("%d / %d = %d", x, y, x / y)) + handleWith2(x, y, + (ctx, x, y) -> + ctx.complete(String.format("%d / %d = %d", x, y, x / y)) ) ), // matches paths like this: /multiply/{x}/{y} path("multiply", xSegment, ySegment).route( // bind handler by reflection - handleWith(xSegment, ySegment, SimpleServerApp8::multiply) + handleWith2(xSegment, ySegment, SimpleServerApp8::multiply) ), path("multiply-methodref", xSegment, ySegment).route( - // bind handler by reflection - handleWith(xSegment, ySegment, new Test(123)::constantPlusMultiply) + // bind handler by reference to new instance of handler + handleWith2(xSegment, ySegment, new Test(123)::constantPlusMultiply) ) ); } diff --git a/akka-http-tests-java8/src/test/java/AllJavaTests.java b/akka-http-tests-java8/src/test/java/AllJavaTests.java index bb81c717af..3736e171a2 100644 --- a/akka-http-tests-java8/src/test/java/AllJavaTests.java +++ b/akka-http-tests-java8/src/test/java/AllJavaTests.java @@ -1,16 +1,14 @@ /* - * Copyright (C) 2009-2014 Typesafe Inc. + * Copyright (C) 2009-2015 Typesafe Inc. */ import akka.http.javadsl.server.HandlerBindingTest; -import docs.http.javadsl.server.HandlerExampleSpec; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ - HandlerBindingTest.class, - HandlerExampleSpec.class + HandlerBindingTest.class }) public class AllJavaTests { } diff --git a/akka-http-tests-java8/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java b/akka-http-tests-java8/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java index 5790232992..cad4872238 100644 --- a/akka-http-tests-java8/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java +++ b/akka-http-tests-java8/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java @@ -8,7 +8,6 @@ import akka.http.scaladsl.model.HttpRequest; import org.junit.Test; import akka.http.javadsl.testkit.*; import akka.http.javadsl.server.values.*; -import static akka.http.javadsl.server.Directives.*; public class HandlerBindingTest extends JUnitRouteTest { Parameter aParam = Parameters.intValue("a"); @@ -24,7 +23,7 @@ public class HandlerBindingTest extends JUnitRouteTest { } @Test public void testHandler1() { - Route route = handleWith(aParam, (ctx, a) -> ctx.complete("Ok " + a)); + Route route = handleWith1(aParam, (ctx, a) -> ctx.complete("Ok " + a)); TestResponse response = runRoute(route, HttpRequest.GET("?a=23")); response.assertStatusCode(200); response.assertEntity("Ok 23"); @@ -32,7 +31,7 @@ public class HandlerBindingTest extends JUnitRouteTest { @Test public void testHandler2() { Route route = - handleWith( + handleWith2( aParam, bParam, (ctx, a, b) -> ctx.complete("Sum: " + (a + b))); @@ -43,7 +42,7 @@ public class HandlerBindingTest extends JUnitRouteTest { @Test public void testHandler3() { Route route = - handleWith( + handleWith3( aParam, bParam, cParam, @@ -55,7 +54,7 @@ public class HandlerBindingTest extends JUnitRouteTest { @Test public void testHandler4() { Route route = - handleWith( + handleWith4( aParam, bParam, cParam, @@ -71,7 +70,7 @@ public class HandlerBindingTest extends JUnitRouteTest { @Test public void testHandler4MethodRef() { Route route = - handleWith( + handleWith4( aParam, bParam, cParam, diff --git a/akka-docs-dev/rst/java/code/docs/http/javadsl/HandlerExampleSpec.java b/akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java similarity index 62% rename from akka-docs-dev/rst/java/code/docs/http/javadsl/HandlerExampleSpec.java rename to akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java index 22c61fb79c..6a766cdbc2 100644 --- a/akka-docs-dev/rst/java/code/docs/http/javadsl/HandlerExampleSpec.java +++ b/akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleDocTest.java @@ -2,8 +2,9 @@ * Copyright (C) 2009-2015 Typesafe Inc. */ -package docs.http.javadsl; +package docs.http.javadsl.server; +import akka.dispatch.Futures; import akka.http.javadsl.model.HttpRequest; import akka.http.javadsl.server.*; import akka.http.javadsl.server.values.Parameters; @@ -12,7 +13,7 @@ import akka.http.javadsl.testkit.JUnitRouteTest; import akka.http.javadsl.testkit.TestRoute; import org.junit.Test; -public class HandlerExampleSpec extends JUnitRouteTest { +public class HandlerExampleDocTest extends JUnitRouteTest { @Test public void testSimpleHandler() { //#simple-handler-example-full @@ -20,7 +21,7 @@ public class HandlerExampleSpec extends JUnitRouteTest { //#simple-handler Handler handler = new Handler() { @Override - public RouteResult handle(RequestContext ctx) { + public RouteResult apply(RequestContext ctx) { return ctx.complete("This was a " + ctx.request().method().value() + " request to "+ctx.request().getUri()); } @@ -67,16 +68,16 @@ public class HandlerExampleSpec extends JUnitRouteTest { RequestVal ySegment = PathMatchers.intValue(); //#handler2 - Handler2 multiply = + final Handler2 multiply = new Handler2() { @Override - public RouteResult handle(RequestContext ctx, Integer x, Integer y) { + public RouteResult apply(RequestContext ctx, Integer x, Integer y) { int result = x * y; return ctx.complete("x * y = " + result); } }; - Route multiplyXAndYParam = handleWith(xParam, yParam, multiply); + final Route multiplyXAndYParam = handleWith2(xParam, yParam, multiply); //#handler2 Route createRoute() { @@ -87,7 +88,7 @@ public class HandlerExampleSpec extends JUnitRouteTest { multiplyXAndYParam ), path("path-multiply", xSegment, ySegment).route( - handleWith(xSegment, ySegment, multiply) + handleWith2(xSegment, ySegment, multiply) ) ) ) @@ -107,6 +108,63 @@ public class HandlerExampleSpec extends JUnitRouteTest { //#handler2-example-full } + @Test + public void testCalculatorJava8() { + //#handler2-java8-example-full + class TestHandler extends akka.http.javadsl.server.AllDirectives { + final RequestVal xParam = Parameters.intValue("x"); + final RequestVal yParam = Parameters.intValue("y"); + + //#handler2-java8 + final Handler2 multiply = + (ctx, x, y) -> ctx.complete("x * y = " + (x * y)); + + final Route multiplyXAndYParam = handleWith2(xParam, yParam, multiply); + //#handler2-java8 + + RouteResult subtract(RequestContext ctx, int x, int y) { + return ctx.complete("x - y = " + (x - y)); + } + + Route createRoute() { + return route( + get( + pathPrefix("calculator").route( + path("multiply").route( + // use Handler explicitly + multiplyXAndYParam + ), + path("add").route( + // create Handler as lambda expression + handleWith2(xParam, yParam, + (ctx, x, y) -> ctx.complete("x + y = " + (x + y))) + ), + path("subtract").route( + // create handler by lifting method + handleWith2(xParam, yParam, this::subtract) + ) + ) + ) + ); + } + } + + // 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/add?x=12&y=42")) + .assertStatusCode(200) + .assertEntity("x + y = 54"); + + r.run(HttpRequest.GET("/calculator/subtract?x=42&y=12")) + .assertStatusCode(200) + .assertEntity("x - y = 30"); + //#handler2-java8-example-full + } + @Test public void testCalculatorReflective() { //#reflective-example-full @@ -124,7 +182,7 @@ public class HandlerExampleSpec extends JUnitRouteTest { return ctx.complete("x * y = " + result); } - Route multiplyXAndYParam = handleWith(this, "multiply", xParam, yParam); + Route multiplyXAndYParam = handleReflectively(this, "multiply", xParam, yParam); //#reflective Route createRoute() { @@ -135,7 +193,7 @@ public class HandlerExampleSpec extends JUnitRouteTest { multiplyXAndYParam ), path("path-multiply", xSegment, ySegment).route( - handleWith(this, "multiply", xSegment, ySegment) + handleWith2(xSegment, ySegment, this::multiply) ) ) ) diff --git a/akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleSpec.java b/akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleSpec.java deleted file mode 100644 index 2f5495d964..0000000000 --- a/akka-http-tests-java8/src/test/java/docs/http/javadsl/server/HandlerExampleSpec.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009-2015 Typesafe Inc. - */ - -package docs.http.javadsl.server; - -import akka.http.javadsl.model.HttpRequest; -import akka.http.javadsl.server.*; -import akka.http.javadsl.server.values.Parameters; -import akka.http.javadsl.testkit.JUnitRouteTest; -import akka.http.javadsl.testkit.TestRoute; -import org.junit.Test; - -public class HandlerExampleSpec extends JUnitRouteTest { - @Test - public void testCalculator() { - //#handler2-example-full - class TestHandler extends akka.http.javadsl.server.AllDirectives { - RequestVal xParam = Parameters.intValue("x"); - RequestVal yParam = Parameters.intValue("y"); - - //#handler2 - Handler2 multiply = - (ctx, x, y) -> ctx.complete("x * y = " + (x * y)); - - Route multiplyXAndYParam = handleWith(xParam, yParam, multiply); - //#handler2 - - Route createRoute() { - return route( - get( - pathPrefix("calculator").route( - path("multiply").route( - multiplyXAndYParam - ), - path("add").route( - handleWith(xParam, yParam, - (ctx, x, y) -> ctx.complete("x + y = " + (x + y))) - ) - ) - ) - ); - } - } - - // 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/add?x=12&y=42")) - .assertStatusCode(200) - .assertEntity("x + y = 54"); - //#handler2-example-full - } -} \ No newline at end of file diff --git a/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/petstore/PetStoreExample.java b/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/petstore/PetStoreExample.java index 9adaae6d01..6098480d87 100644 --- a/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/petstore/PetStoreExample.java +++ b/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/petstore/PetStoreExample.java @@ -26,7 +26,7 @@ public class PetStoreExample { final RequestVal existingPet = RequestVals.lookupInMap(petId, Pet.class, pets); Handler1 putPetHandler = new Handler1() { - public RouteResult handle(RequestContext ctx, Pet thePet) { + public RouteResult apply(RequestContext ctx, Pet thePet) { pets.put(thePet.getId(), thePet); return ctx.completeAs(Jackson.json(), thePet); } @@ -44,10 +44,10 @@ public class PetStoreExample { get(extractAndComplete(Jackson.json(), existingPet)), // 2. using a handler - put(handleWith(petEntity, putPetHandler)), + put(handleWith1(petEntity, putPetHandler)), // 3. calling a method of a controller instance reflectively - delete(handleWith(controller, "deletePet", petId)) + delete(handleReflectively(controller, "deletePet", petId)) ) ); } diff --git a/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java b/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java index b17e6fbd43..4526373906 100644 --- a/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java +++ b/akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java @@ -41,7 +41,7 @@ public class SimpleServerApp extends HttpApp { public Route createRoute() { Handler addHandler = new Handler() { @Override - public RouteResult handle(RequestContext ctx) { + public RouteResult apply(RequestContext ctx) { int xVal = x.get(ctx); int yVal = y.get(ctx); int result = xVal + yVal; @@ -49,7 +49,7 @@ public class SimpleServerApp extends HttpApp { } }; Handler2 subtractHandler = new Handler2() { - public RouteResult handle(RequestContext ctx, Integer xVal, Integer yVal) { + public RouteResult apply(RequestContext ctx, Integer xVal, Integer yVal) { int result = xVal - yVal; return ctx.complete(String.format("%d - %d = %d", xVal, yVal, result)); } @@ -57,7 +57,7 @@ public class SimpleServerApp extends HttpApp { Handler1 helloPostHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, String s) { + public RouteResult apply(RequestContext ctx, String s) { return ctx.complete("Hello " + s + "!"); } }; @@ -72,20 +72,20 @@ public class SimpleServerApp extends HttpApp { handleWith(addHandler, x, y) ), path("subtract").route( - handleWith(x, y, subtractHandler) + handleWith2(x, y, subtractHandler) ), // matches paths like this: /multiply/{x}/{y} path("multiply", xSegment, ySegment).route( // bind handler by reflection - handleWith(SimpleServerApp.class, "multiply", xSegment, ySegment) + handleReflectively(SimpleServerApp.class, "multiply", xSegment, ySegment) ), path("multiplyAsync", xSegment, ySegment).route( // bind async handler by reflection - handleWith(SimpleServerApp.class, "multiplyAsync", xSegment, ySegment) + handleReflectively(SimpleServerApp.class, "multiplyAsync", xSegment, ySegment) ), post( path("hello").route( - handleWith(bodyAsName, helloPostHandler) + handleWith1(bodyAsName, helloPostHandler) ) ) ); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/CompleteTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/CompleteTest.java index bc2082b679..e5a72c777f 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/CompleteTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/CompleteTest.java @@ -51,7 +51,7 @@ public class CompleteTest extends JUnitRouteTest { Handler2 slowCalc = new Handler2() { @Override - public RouteResult handle(final RequestContext ctx, final Integer x, final Integer y) { + public RouteResult apply(final RequestContext ctx, final Integer x, final Integer y) { return ctx.completeWith(Futures.future(new Callable() { @Override public RouteResult call() throws Exception { @@ -62,7 +62,7 @@ public class CompleteTest extends JUnitRouteTest { } }; - Route route = handleWith(x, y, slowCalc); + Route route = handleWith2(x, y, slowCalc); runRoute(route, HttpRequest.GET("add?x=42&y=23")) .assertStatusCode(200) .assertEntity("42 + 23 = 65"); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java index 866e41c96c..20b51c50e4 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/HandlerBindingTest.java @@ -14,12 +14,12 @@ public class HandlerBindingTest extends JUnitRouteTest { @Test public void testHandlerWithoutExtractions() { Route route = handleWith( - new Handler() { - @Override - public RouteResult handle(RequestContext ctx) { - return ctx.complete("Ok"); + new Handler() { + @Override + public RouteResult apply(RequestContext ctx) { + return ctx.complete("Ok"); + } } - } ); runRoute(route, HttpRequest.GET("/")) .assertEntity("Ok"); @@ -30,12 +30,12 @@ public class HandlerBindingTest extends JUnitRouteTest { final Parameter b = Parameters.intValue("b"); Route route = handleWith( - new Handler() { - @Override - public RouteResult handle(RequestContext ctx) { - return ctx.complete("Ok a:" + a.get(ctx) +" b:" + b.get(ctx)); - } - }, a, b + new Handler() { + @Override + public RouteResult apply(RequestContext ctx) { + return ctx.complete("Ok a:" + a.get(ctx) + " b:" + b.get(ctx)); + } + }, a, b ); runRoute(route, HttpRequest.GET("?a=23&b=42")) .assertEntity("Ok a:23 b:42"); @@ -45,12 +45,12 @@ public class HandlerBindingTest extends JUnitRouteTest { final Parameter a = Parameters.intValue("a"); Route route = handleWith( - new Handler() { - @Override - public RouteResult handle(RequestContext ctx) { - return ctx.complete("Ok " + a.get(ctx)); - } - }, a + new Handler() { + @Override + public RouteResult apply(RequestContext ctx) { + return ctx.complete("Ok " + a.get(ctx)); + } + }, a ); runRoute(route, HttpRequest.GET("/")) .assertStatusCode(404) @@ -60,14 +60,13 @@ public class HandlerBindingTest extends JUnitRouteTest { public void testHandler1() { final Parameter a = Parameters.intValue("a"); - Route route = handleWith( - a, - new Handler1() { - @Override - public RouteResult handle(RequestContext ctx, Integer a) { - return ctx.complete("Ok " + a); + Route route = handleWith1(a, + new Handler1() { + @Override + public RouteResult apply(RequestContext ctx, Integer a) { + return ctx.complete("Ok " + a); + } } - } ); runRoute(route, HttpRequest.GET("?a=23")) .assertStatusCode(200) @@ -75,12 +74,12 @@ public class HandlerBindingTest extends JUnitRouteTest { } @Test public void testHandler2() { - Route route = handleWith( + Route route = handleWith2( Parameters.intValue("a"), Parameters.intValue("b"), new Handler2() { @Override - public RouteResult handle(RequestContext ctx, Integer a, Integer b) { + public RouteResult apply(RequestContext ctx, Integer a, Integer b) { return ctx.complete("Sum: " + (a + b)); } } @@ -91,13 +90,13 @@ public class HandlerBindingTest extends JUnitRouteTest { } @Test public void testHandler3() { - Route route = handleWith( + Route route = handleWith3( Parameters.intValue("a"), Parameters.intValue("b"), Parameters.intValue("c"), new Handler3() { @Override - public RouteResult handle(RequestContext ctx, Integer a, Integer b, Integer c) { + public RouteResult apply(RequestContext ctx, Integer a, Integer b, Integer c) { return ctx.complete("Sum: " + (a + b + c)); } } @@ -108,14 +107,14 @@ public class HandlerBindingTest extends JUnitRouteTest { } @Test public void testHandler4() { - Route route = handleWith( + Route route = handleWith4( Parameters.intValue("a"), Parameters.intValue("b"), Parameters.intValue("c"), Parameters.intValue("d"), new Handler4() { @Override - public RouteResult handle(RequestContext ctx, Integer a, Integer b, Integer c, Integer d) { + public RouteResult apply(RequestContext ctx, Integer a, Integer b, Integer c, Integer d) { return ctx.complete("Sum: " + (a + b + c + d)); } } @@ -131,7 +130,7 @@ public class HandlerBindingTest extends JUnitRouteTest { return ctx.complete("Negated: " + (- a)); } } - Route route = handleWith(new Test(), "negate", Parameters.intValue("a")); + Route route = handleReflectively(new Test(), "negate", Parameters.intValue("a")); runRoute(route, HttpRequest.GET("?a=23")) .assertStatusCode(200) .assertEntity("Negated: -23"); @@ -142,7 +141,7 @@ public class HandlerBindingTest extends JUnitRouteTest { } @Test public void testStaticReflectiveHandler() { - Route route = handleWith(HandlerBindingTest.class, "squared", Parameters.intValue("a")); + Route route = handleReflectively(HandlerBindingTest.class, "squared", Parameters.intValue("a")); runRoute(route, HttpRequest.GET("?a=23")) .assertStatusCode(200) .assertEntity("Squared: 529"); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/MarshallerTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/MarshallerTest.java index 45b09cd6e4..81a83f4da7 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/MarshallerTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/MarshallerTest.java @@ -37,7 +37,7 @@ public class MarshallerTest extends JUnitRouteTest { Handler1 nummerHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, Integer integer) { + public RouteResult apply(RequestContext ctx, Integer integer) { return ctx.completeAs(numberAsNameMarshaller, integer); } }; @@ -46,7 +46,7 @@ public class MarshallerTest extends JUnitRouteTest { testRoute( get( path("nummer").route( - handleWith(n, nummerHandler) + handleWith1(n, nummerHandler) ) ) ); @@ -88,7 +88,7 @@ public class MarshallerTest extends JUnitRouteTest { Handler1 nummerHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, Integer integer) { + public RouteResult apply(RequestContext ctx, Integer integer) { return ctx.completeAs(numberAsJsonListMarshaller, integer); } }; @@ -97,7 +97,7 @@ public class MarshallerTest extends JUnitRouteTest { testRoute( get( path("nummer").route( - handleWith(n, nummerHandler) + handleWith1(n, nummerHandler) ) ) ); @@ -132,7 +132,7 @@ public class MarshallerTest extends JUnitRouteTest { Handler1 nummerHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, Integer integer) { + public RouteResult apply(RequestContext ctx, Integer integer) { return ctx.completeAs(numberAsJsonListMarshaller, integer); } }; @@ -141,7 +141,7 @@ public class MarshallerTest extends JUnitRouteTest { testRoute( get( path("nummer").route( - handleWith(n, nummerHandler) + handleWith1(n, nummerHandler) ) ) ); @@ -176,7 +176,7 @@ public class MarshallerTest extends JUnitRouteTest { Handler1 nummerHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, Integer integer) { + public RouteResult apply(RequestContext ctx, Integer integer) { return ctx.completeAs(numberAsJsonListMarshaller, integer); } }; @@ -185,7 +185,7 @@ public class MarshallerTest extends JUnitRouteTest { testRoute( get( path("nummer").route( - handleWith(n, nummerHandler) + handleWith1(n, nummerHandler) ) ) ); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/ExecutionDirectivesTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/ExecutionDirectivesTest.java index 39a1ba7fca..71fc1c95d6 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/ExecutionDirectivesTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/ExecutionDirectivesTest.java @@ -19,7 +19,7 @@ public class ExecutionDirectivesTest extends JUnitRouteTest { Handler2 divide = new Handler2() { @Override - public RouteResult handle(RequestContext ctx, Integer a, Integer b) { + public RouteResult apply(RequestContext ctx, Integer a, Integer b) { int result = a / b; return ctx.complete("The result is: " + result); } @@ -44,7 +44,7 @@ public class ExecutionDirectivesTest extends JUnitRouteTest { testRoute( handleExceptions(handleDivByZero, path("divide").route( - handleWith(a, b, divide) + handleWith2(a, b, divide) ) ) ); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/PathDirectivesTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/PathDirectivesTest.java index ce46bdac60..c3235bf20d 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/PathDirectivesTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/directives/PathDirectivesTest.java @@ -239,9 +239,9 @@ public class PathDirectivesTest extends JUnitRouteTest { TestRoute route = testRoute( path("multiply", x, "with", y).route( - handleWith(x, y, new Handler2() { + handleWith2(x, y, new Handler2() { @Override - public RouteResult handle(RequestContext ctx, Integer x, Integer y) { + public RouteResult apply(RequestContext ctx, Integer x, Integer y) { return ctx.complete(String.format("%d * %d = %d", x, y, x * y)); } }) diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/values/HttpBasicAuthenticationTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/values/HttpBasicAuthenticationTest.java index 937063ff02..de4368ca28 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/values/HttpBasicAuthenticationTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/values/HttpBasicAuthenticationTest.java @@ -29,7 +29,7 @@ public class HttpBasicAuthenticationTest extends JUnitRouteTest { Handler1 helloWorldHandler = new Handler1() { @Override - public RouteResult handle(RequestContext ctx, String user) { + public RouteResult apply(RequestContext ctx, String user) { return ctx.complete("Hello "+user+"!"); } }; @@ -38,7 +38,7 @@ public class HttpBasicAuthenticationTest extends JUnitRouteTest { testRoute( path("secure").route( authenticatedUser.route( - handleWith(authenticatedUser, helloWorldHandler) + handleWith1(authenticatedUser, helloWorldHandler) ) ) ); diff --git a/akka-http-tests/src/test/java/akka/http/javadsl/server/values/ParametersTest.java b/akka-http-tests/src/test/java/akka/http/javadsl/server/values/ParametersTest.java index 45b14c895e..3dce146173 100644 --- a/akka-http-tests/src/test/java/akka/http/javadsl/server/values/ParametersTest.java +++ b/akka-http-tests/src/test/java/akka/http/javadsl/server/values/ParametersTest.java @@ -274,9 +274,9 @@ public class ParametersTest extends JUnitRouteTest { @Test public void testParametersAsMapExtraction() { - TestRoute route = testRoute(handleWith(paramMap, new Handler1>(){ + TestRoute route = testRoute(handleWith1(paramMap, new Handler1>(){ @Override - public RouteResult handle(RequestContext ctx, Map paramMap) { + public RouteResult apply(RequestContext ctx, Map paramMap) { ArrayList keys = new ArrayList(paramMap.keySet()); Collections.sort(keys); StringBuilder res = new StringBuilder(); @@ -305,9 +305,9 @@ public class ParametersTest extends JUnitRouteTest { } @Test public void testParametersAsMultiMapExtraction() { - TestRoute route = testRoute(handleWith(paramMultiMap, new Handler1>>(){ + TestRoute route = testRoute(handleWith1(paramMultiMap, new Handler1>>(){ @Override - public RouteResult handle(RequestContext ctx, Map> paramMap) { + public RouteResult apply(RequestContext ctx, Map> paramMap) { ArrayList keys = new ArrayList(paramMap.keySet()); Collections.sort(keys); StringBuilder res = new StringBuilder(); @@ -342,9 +342,9 @@ public class ParametersTest extends JUnitRouteTest { } @Test public void testParametersAsCollectionExtraction() { - TestRoute route = testRoute(handleWith(paramEntries, new Handler1>>(){ + TestRoute route = testRoute(handleWith1(paramEntries, new Handler1>>(){ @Override - public RouteResult handle(RequestContext ctx, Collection> paramEntries) { + public RouteResult apply(RequestContext ctx, Collection> paramEntries) { ArrayList> entries = new ArrayList>(paramEntries); Collections.sort(entries, new Comparator>() { @Override diff --git a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/SchemeDirectivesSpec.scala b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/SchemeDirectivesSpec.scala index df08e5861f..8ae590dd41 100644 --- a/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/SchemeDirectivesSpec.scala +++ b/akka-http-tests/src/test/scala/akka/http/scaladsl/server/directives/SchemeDirectivesSpec.scala @@ -5,8 +5,6 @@ package akka.http.scaladsl.server package directives -import akka.http.scaladsl.model.StatusCodes._ - class SchemeDirectivesSpec extends RoutingSpec { "the extractScheme directive" should { "extract the Uri scheme" in { diff --git a/akka-http/src/main/boilerplate/akka/http/javadsl/server/Handlers.scala.template b/akka-http/src/main/boilerplate/akka/http/javadsl/server/Handlers.scala.template new file mode 100644 index 0000000000..1bcf458e23 --- /dev/null +++ b/akka-http/src/main/boilerplate/akka/http/javadsl/server/Handlers.scala.template @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009-2015 Typesafe Inc. + */ +package akka.http.javadsl.server + +import scala.concurrent.Future + +[..21#/** + * A route Handler that handles a request (that is encapsulated in a [[RequestContext]]) + * and returns a [[RouteResult]] with the response (or the rejection). + * + * A route `Handler1` is a convenience class that extends Function of arity `N+1`, + * since it needs to pass along the [[RequestContext]] as well, yet for readability + * purposes we can see it as "handles 1 route arguments". + * + * Use the methods in [[RequestContext]] to create a [[RouteResult]]. + * A handler MUST NOT return `null` as the result. + */ +trait Handler1[[#T1#]] extends akka.japi.function.Function2[RequestContext, [#T1#], RouteResult] { + override def apply(ctx: RequestContext, [#t1: T1#]): RouteResult +} +/** + * A route Handler that handles a request (that is encapsulated in a [[RequestContext]]) + * and returns a [[scala.concurrent.Future]] of [[RouteResult]] with the response (or the rejection). + * + * A route `Handler1` is a convenience class that extends Function of arity `N+1`, + * since it needs to pass along the [[RequestContext]] as well, yet for readability + * purposes we can see it as "handles 1 route arguments". + * + * Use the methods in [[RequestContext]] to create a [[RouteResult]]. + * A handler MUST NOT return `null` as the result. + */ +trait AsyncHandler1[[#T1#]] extends akka.japi.function.Function2[RequestContext, [#T1#], Future[RouteResult]] { + override def apply(ctx: RequestContext, [#t1: T1#]): Future[RouteResult] +}# + +] diff --git a/akka-http/src/main/boilerplate/akka/http/javadsl/server/directives/BasicDirectivesBase.scala.template b/akka-http/src/main/boilerplate/akka/http/javadsl/server/directives/BasicDirectivesBase.scala.template new file mode 100644 index 0000000000..105aceaa47 --- /dev/null +++ b/akka-http/src/main/boilerplate/akka/http/javadsl/server/directives/BasicDirectivesBase.scala.template @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009-2015 Typesafe Inc. + */ +package akka.http.javadsl.server.directives + +import akka.http.javadsl.server.Route +import akka.http.javadsl.server.RouteResult +import akka.http.javadsl.server.RequestVal +import akka.http.javadsl.server.RequestContext +import scala.annotation.varargs +import scala.concurrent.Future + +abstract class BasicDirectivesBase { + /** INTERNAL API */ + private[http] def handle(extractions: RequestVal[_]*)(f: RequestContext ⇒ RouteResult): Route + + /** + * Handles the route using the given function. + * The function MUST NOT return `null`. + * + * If the `handler` is accessing request values these must be passed to this method in order for extraction to be performed. + */ + @varargs def handleWith(handler: akka.japi.function.Function[RequestContext, RouteResult], extractions: RequestVal[_]*): Route = + handle(extractions: _*)(ctx => handler(ctx)) + + /** + * Handles the route using the given function, completing the route once the returned [[scala.concurrent.Future]] completes. + * The function MUST NOT return `null`. + * + * If the `handler` is accessing request values these must be passed to this method in order for extraction to be performed. + */ + @varargs def handleWithAsync(handler: akka.japi.function.Function[RequestContext, Future[RouteResult]], extractions: RequestVal[_]*): Route = + handle(extractions: _*)(ctx => ctx.completeWith(handler(ctx))) + + + [..21#/** + * Handles the route using the given function. The function MUST NOT return `null`. + * + * For convenience, using Java 8 lambda expressions as the `handler` function is recommended. + * For Java 6 or 7 users the convenience [[akka.http.javadsl.server.Handler1]] class (which itself extends + * [[akka.japi.function.Function2]] should prove to be useful, as it matches naming-wise with the number of + * handled request values. + */ + def handleWith1[[#T1#]]([#v1: RequestVal[T1]#], handler: akka.japi.function.Function2[RequestContext, [#T1#], RouteResult]): Route = + handle([#v1#])(ctx => handler(ctx, [#v1.get(ctx)#])) + + /** + * Handles the route using the given function, completing the route once the returned [[scala.concurrent.Future]] completes. + * The function MUST NOT return `null`. + * + * For convenience, using Java 8 lambda expressions as the `handler` function is recommended. + * For Java 6 or 7 users the convenience [[akka.http.javadsl.server.Handler1]] class (which itself extends + * [[akka.japi.function.Function2]] should prove to be useful, as it matches naming-wise with the number of + * handled request values. + */ + def handleWithAsync1[[#T1#]]([#v1: RequestVal[T1]#], handler: akka.japi.function.Function2[RequestContext, [#T1#], Future[RouteResult]]): Route = + handle([#v1#])(ctx => ctx.completeWith(handler(ctx, [#v1.get(ctx)#])))# + + ] + +} diff --git a/akka-http/src/main/scala/akka/http/javadsl/server/Handler.scala b/akka-http/src/main/scala/akka/http/javadsl/server/Handler.scala index ec878011af..b95e1c3383 100644 --- a/akka-http/src/main/scala/akka/http/javadsl/server/Handler.scala +++ b/akka-http/src/main/scala/akka/http/javadsl/server/Handler.scala @@ -1,46 +1,33 @@ /* - * Copyright (C) 2009-2014 Typesafe Inc. + * Copyright (C) 2009-2015 Typesafe Inc. */ - package akka.http.javadsl.server +import scala.concurrent.Future + /** * A route Handler that handles a request (that is encapsulated in a [[RequestContext]]) * and returns a [[RouteResult]] with the response (or the rejection). * - * Use the methods in [[RequestContext]] to create a [[RouteResult]]. A handler mustn't - * return [[null]] as the result. + * Use the methods in [[RequestContext]] to create a [[RouteResult]]. + * A handler MUST NOT return `null` as the result. + * + * See also [[Handler1]], [[Handler2]], ..., until [[Handler21]] for handling `N` request values. */ //#handler -trait Handler { - def handle(ctx: RequestContext): RouteResult +trait Handler extends akka.japi.function.Function[RequestContext, RouteResult] { + override def apply(ctx: RequestContext): RouteResult } //#handler /** - * A route handler with one additional argument. + * A route Handler that handles a request (that is encapsulated in a [[RequestContext]]) + * and returns a [[scala.concurrent.Future]] of [[RouteResult]] with the response (or the rejection). + * + * Use the methods in [[RequestContext]] to create a [[RouteResult]]. + * A handler MUST NOT return `null` as the result. */ -trait Handler1[T1] { - def handle(ctx: RequestContext, t1: T1): RouteResult +trait AsyncHandler extends akka.japi.function.Function[RequestContext, Future[RouteResult]] { + override def apply(ctx: RequestContext): Future[RouteResult] } -/** - * A route handler with two additional arguments. - */ -trait Handler2[T1, T2] { - def handle(ctx: RequestContext, t1: T1, t2: T2): RouteResult -} - -/** - * A route handler with three additional arguments. - */ -trait Handler3[T1, T2, T3] { - def handle(ctx: RequestContext, t1: T1, t2: T2, t3: T3): RouteResult -} - -/** - * A route handler with four additional arguments. - */ -trait Handler4[T1, T2, T3, T4] { - def handle(ctx: RequestContext, t1: T1, t2: T2, t3: T3, t4: T4): RouteResult -} \ No newline at end of file diff --git a/akka-http/src/main/scala/akka/http/javadsl/server/directives/BasicDirectives.scala b/akka-http/src/main/scala/akka/http/javadsl/server/directives/BasicDirectives.scala index 419f976107..929cbdece4 100644 --- a/akka-http/src/main/scala/akka/http/javadsl/server/directives/BasicDirectives.scala +++ b/akka-http/src/main/scala/akka/http/javadsl/server/directives/BasicDirectives.scala @@ -4,17 +4,18 @@ package akka.http.javadsl.server.directives -import scala.annotation.varargs -import java.lang.reflect.{ ParameterizedType, Method } +import java.lang.reflect.{ Method, ParameterizedType } import akka.http.javadsl.model.{ Uri, ContentType, StatusCode, HttpResponse } -import akka.http.javadsl.server._ import akka.http.impl.server.RouteStructure._ import akka.http.impl.server._ +import akka.http.javadsl.model.{ ContentType, HttpResponse, StatusCode } +import akka.http.javadsl.server._ +import scala.annotation.varargs import scala.concurrent.Future -abstract class BasicDirectives { +abstract class BasicDirectives extends BasicDirectivesBase { /** * Tries the given route alternatives in sequence until the first one matches. */ @@ -84,40 +85,6 @@ abstract class BasicDirectives { def extractHere(extractions: RequestVal[_]*): Directive = Directives.custom(Extract(extractions.map(_.asInstanceOf[StandaloneExtractionImpl[_ <: AnyRef]]))) - /** - * A route that handles the request with the given opaque handler. Specify a set of extractions - * that will be used in the handler to make sure they are available. - */ - @varargs - def handleWith[T1](handler: Handler, extractions: RequestVal[_]*): Route = - handle(extractions: _*)(handler.handle(_)) - - /** - * A route that handles the request given the value of a single [[RequestVal]]. - */ - def handleWith[T1](e1: RequestVal[T1], handler: Handler1[T1]): Route = - handle(e1)(ctx ⇒ handler.handle(ctx, e1.get(ctx))) - - /** - * A route that handles the request given the values of the given [[RequestVal]]s. - */ - def handleWith[T1, T2](e1: RequestVal[T1], e2: RequestVal[T2], handler: Handler2[T1, T2]): Route = - handle(e1, e2)(ctx ⇒ handler.handle(ctx, e1.get(ctx), e2.get(ctx))) - - /** - * A route that handles the request given the values of the given [[RequestVal]]s. - */ - def handleWith[T1, T2, T3]( - e1: RequestVal[T1], e2: RequestVal[T2], e3: RequestVal[T3], handler: Handler3[T1, T2, T3]): Route = - handle(e1, e2, e3)(ctx ⇒ handler.handle(ctx, e1.get(ctx), e2.get(ctx), e3.get(ctx))) - - /** - * A route that handles the request given the values of the given [[RequestVal]]s. - */ - def handleWith[T1, T2, T3, T4]( - e1: RequestVal[T1], e2: RequestVal[T2], e3: RequestVal[T3], e4: RequestVal[T4], handler: Handler4[T1, T2, T3, T4]): Route = - handle(e1, e2, e3, e4)(ctx ⇒ handler.handle(ctx, e1.get(ctx), e2.get(ctx), e3.get(ctx), e4.get(ctx))) - private[http] def handle(extractions: RequestVal[_]*)(f: RequestContext ⇒ RouteResult): Route = { val route = new OpaqueRoute() { @@ -137,8 +104,8 @@ abstract class BasicDirectives { * public static RouteResult methodName(RequestContext ctx, T1 t1, T2 t2, ...) */ @varargs - def handleWith(instance: AnyRef, methodName: String, extractions: RequestVal[_]*): Route = - handleWith(instance.getClass, instance, methodName, extractions: _*) + def handleReflectively(instance: AnyRef, methodName: String, extractions: RequestVal[_]*): Route = + handleReflectively(instance.getClass, instance, methodName, extractions: _*) /** * Handles the route by reflectively calling the static method specified by `clazz`, and `methodName`. @@ -149,8 +116,8 @@ abstract class BasicDirectives { * public static RouteResult methodName(RequestContext ctx, T1 t1, T2 t2, ...) */ @varargs - def handleWith(clazz: Class[_], methodName: String, extractions: RequestVal[_]*): Route = - handleWith(clazz, null, methodName, extractions: _*) + def handleReflectively(clazz: Class[_], methodName: String, extractions: RequestVal[_]*): Route = + handleReflectively(clazz, null, methodName, extractions: _*) /** * Handles the route by calling the method specified by `clazz`, `instance`, and `methodName`. Additionally, the value @@ -161,7 +128,7 @@ abstract class BasicDirectives { * public static RouteResult methodName(RequestContext ctx, T1 t1, T2 t2, ...) */ @varargs - def handleWith(clazz: Class[_], instance: AnyRef, methodName: String, extractions: RequestVal[_]*): Route = { + def handleReflectively(clazz: Class[_], instance: AnyRef, methodName: String, extractions: RequestVal[_]*): Route = { def chooseOverload(methods: Seq[Method]): (RequestContext, Seq[Any]) ⇒ RouteResult = { val extractionTypes = extractions.map(_.resultClass).toList val RequestContextClass = classOf[RequestContext]