From 23a15593ee769ff61884c9bd84fd20653f2ea6c9 Mon Sep 17 00:00:00 2001 From: Daniel Kec Date: Mon, 11 Jul 2022 15:58:42 +0200 Subject: [PATCH 1/2] Routing 3 doc update Signed-off-by: Daniel Kec --- docs/se/webserver.adoc | 33 +++++++++++++++++++ docs/se/websocket.adoc | 74 +++++++++++++++++++++++++++++++----------- 2 files changed, 88 insertions(+), 19 deletions(-) diff --git a/docs/se/webserver.adoc b/docs/se/webserver.adoc index a9dd4c480f0..bd41f81225d 100644 --- a/docs/se/webserver.adoc +++ b/docs/se/webserver.adoc @@ -31,7 +31,9 @@ include::{rootdir}/includes/se.adoc[] - <> - <> - <> +- <> - <> +- <> - <> - <> - <> @@ -299,6 +301,22 @@ To complete the request handling, you must send a response by calling the `res.s <1> handler that terminates the request handling for any HTTP method using the `/hello` path <2> send the response +== Protocol Specific Routing +Handling routes based on the protocol version is possible by registering specific routes +on routing builder. + +[source,java] +.Routing based on HTTP version +---- +.routing(r -> r + .get("/any-version", (req, res) -> res.send("HTTP Version " + req.version())) + .route(Http1Route.route(GET, "/version-specific", (req, res) -> res.send("HTTP/1.1 route"))) + .route(Http2Route.route(GET, "/version-specific", (req, res) -> res.send("HTTP/2 route"))) +) +---- + +While `Http1Route` for Http/1 is always available with Helidon webserver, +other routes like `Http2Route` for <> needs to be added as additional dependency. == Error Handling @@ -377,6 +395,21 @@ exception called `req.next()`, then the exception is translated to an HTTP respo * Otherwise, the exceptions are translated to an Internal Server Error HTTP error code `500`. +== Http/2 Support + +Helidon supports Http/2 upgrade from Http/1 and Http/2 without prior knowledge. +Http/2 support is enabled in webserver by default when it's artefact is available on classpath. + +=== Maven Coordinates +To enable Http/2 support add the following dependency to your project's `pom.xml`. + +[source,xml] +---- + + io.helidon.webserver + helidon-webserver-http2 + +---- == Static Content Support diff --git a/docs/se/websocket.adoc b/docs/se/websocket.adoc index 8a076ae6e87..a96871284e6 100644 --- a/docs/se/websocket.adoc +++ b/docs/se/websocket.adoc @@ -21,10 +21,19 @@ :keywords: helidon, webserver, websocket, se :rootdir: {docdir}/.. + include::{rootdir}/includes/se.adoc[] +== ToC + +- <> +- <> +- <> +- <> + +== Overview Helidon integrates with link:https://projects.eclipse.org/projects/ee4j.tyrus[Tyrus] to provide support for the - {jakarta-websocket-spec-url}[Jakarta WebSocket API]. +{jakarta-websocket-spec-url}[Jakarta WebSocket API]. The WebSocket API enables Java applications to participate in WebSocket interactions as both servers and clients. The server API supports two flavors: annotated and programmatic endpoints. @@ -36,11 +45,21 @@ more flexible since they allow different method signatures depending on the application needs, whereas programmatic endpoints must implement an interface and are, therefore, bounded to its definition. -Helidon SE support is based on the `TyrusSupport` class which is -akin to `JerseySupport`, and enables Helidon application to -defined both annotated and programmatic WebSocket endpoints. +Helidon SE support is based on the `WebSocketRouting` class which enables Helidon application to +configure routing for both annotated and programmatic WebSocket endpoints. + + +include::{rootdir}/includes/dependencies.adoc[] -== Helidon SE Example +[source,xml] +---- + + io.helidon.webserver + helidon-webserver-websocket + +---- + +== Example This section describes the implementation of a simple application that uses a REST resource to push messages into a shared queue and a @@ -64,8 +83,12 @@ public class MessageQueueService implements Service { } private void handlePost(ServerRequest request, ServerResponse response) { - request.content().as(String.class).thenAccept(messageQueue::push); - response.status(204).send(); + request.content() + .as(String.class) + .thenAccept(it -> { + messageQueue.push(it); + response.status(204).send(); + }); } } ---- @@ -89,6 +112,7 @@ public class MessageBoardEndpoint extends Endpoint { @Override public void onMessage(String message) { try { + // Send all messages in the queue if (message.equals("SEND")) { while (!messageQueue.isEmpty()) { session.getBasicRemote().sendObject(messageQueue.pop()); @@ -114,20 +138,27 @@ the web server. This is accomplished via a `Routing` builder: [source,java] ---- - List> encoders = - Collections.singletonList(UppercaseEncoder.class); - - Routing.builder() - .register("/rest", new MessageQueueService()) - .register("/websocket", - TyrusSupport.builder().register( - ServerEndpointConfig.Builder.create( - MessageBoardEndpoint.class, "/board").encoders( - encoders).build()).build()) - .build(); +List> encoders = + Collections.singletonList(UppercaseEncoder.class); + +WebServer server = WebServer.builder() + .port(8080) + .routing(r -> r + .register("/web", StaticContentSupport.builder("/WEB") + .welcomeFileName("index.html") + .build()) + .register("/rest", new MessageQueueService()) + ) + .addRouting(WebSocketRouting.builder() + .endpoint("/websocket", ServerEndpointConfig.Builder.create(MessageBoardEndpoint.class, "/board") + .encoders(encoders) + .build()) + .build() + ) + .build() ---- -This code snippet uses multiple builders for `Routing`, `TyrusSupport` and `ServerEndpointConfig`. +This code snippet uses multiple builders for `Routing`, `WebSocketRouting` and `ServerEndpointConfig`. In particular, it registers `MessageBoardEndpoint.class` at `"/websocket/board"` and associates with it a _message encoder_. For more information on message encoders and decoders the reader see the {jakarta-websocket-spec-url}[websocket specification]; in this @@ -138,3 +169,8 @@ Endpoint methods in Helidon SE are executed in Netty's worker thread pool. Threa pool are intended to be _non-blocking_, thus it is recommended for any blocking or long-running operation triggered by an endpoint method to be executed using a separate thread pool. See the documentation for `io.helidon.common.configurable.ThreadPoolSupplier`. + +== Reference + +* link:{javadoc-base-url}/io.helidon.webserver.websocket/module-summary.html[Helidon WebSocket JavaDoc] +* link:{jakarta-websocket-spec-url}[Jakarta WebSocket Specification] From c884426fe2bb410a9430229a57e5a6ac2d36fcb4 Mon Sep 17 00:00:00 2001 From: Daniel Kec Date: Tue, 12 Jul 2022 14:06:36 +0200 Subject: [PATCH 2/2] Review issues Signed-off-by: Daniel Kec --- docs/se/webserver.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/se/webserver.adoc b/docs/se/webserver.adoc index bd41f81225d..21cecdd9f0d 100644 --- a/docs/se/webserver.adoc +++ b/docs/se/webserver.adoc @@ -397,7 +397,8 @@ error code `500`. == Http/2 Support -Helidon supports Http/2 upgrade from Http/1 and Http/2 without prior knowledge. +Helidon supports Http/2 upgrade from Http/1, Http/2 without prior knowledge +and Http/2 with ALPN over TLS. Http/2 support is enabled in webserver by default when it's artefact is available on classpath. === Maven Coordinates