Skip to content

Commit aa5c9da

Browse files
committed
Netty docs
1 parent 756b849 commit aa5c9da

File tree

1 file changed

+53
-36
lines changed

1 file changed

+53
-36
lines changed

doc/server/netty.md

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
To expose an endpoint using a [Netty](https://netty.io)-based server, first add the following dependency:
44

55
```scala
6-
// if you are using Future or just exploring:
7-
"com.softwaremill.sttp.tapir" %% "tapir-netty-server" % "@VERSION@"
8-
9-
// if you want to use Java 21 Loom virtual threads in direct style:
6+
// if you want to use Java 21+ Virtual Threads & direct-style:
107
"com.softwaremill.sttp.tapir" %% "tapir-netty-server-sync" % "@VERSION@"
118

9+
// if you are using Future:
10+
"com.softwaremill.sttp.tapir" %% "tapir-netty-server" % "@VERSION@"
11+
1212
// if you are using cats-effect:
1313
"com.softwaremill.sttp.tapir" %% "tapir-netty-server-cats" % "@VERSION@"
1414

@@ -18,18 +18,20 @@ To expose an endpoint using a [Netty](https://netty.io)-based server, first add
1818

1919
Then, use:
2020

21+
- `NettySyncServer().addEndpoints` to expose direct-style server endpoints (using Virtual Threads).
2122
- `NettyFutureServer().addEndpoints` to expose `Future`-based server endpoints.
22-
- `NettySyncServer().addEndpoints` to expose `Loom`-based server endpoints.
23-
- `NettyCatsServer().addEndpoints` to expose `F`-based server endpoints, where `F` is any cats-effect supported effect. [Streaming](../endpoint/streaming.md) request and response bodies is supported with fs2.
24-
- `NettyZioServer().addEndpoints` to expose `ZIO`-based server endpoints, where `R` represents ZIO requirements supported effect. Streaming is supported with ZIO Streams.
23+
- `NettyCatsServer().addEndpoints` to expose `F`-based server endpoints, where `F` is any cats-effect supported effect.
24+
[Streaming](../endpoint/streaming.md) request and response bodies is supported with fs2.
25+
- `NettyZioServer().addEndpoints` to expose `ZIO`-based server endpoints, where `R` represents ZIO requirements
26+
supported effect. Streaming is supported with ZIO Streams.
2527

2628
These methods require a single, or a list of `ServerEndpoint`s, which can be created by adding [server logic](logic.md)
2729
to an endpoint.
2830

2931
For example:
3032

3133
```scala mdoc:compile-only
32-
import sttp.tapir.*
34+
import sttp.tapir.*
3335
import sttp.tapir.server.netty.{NettyFutureServer, NettyFutureServerBinding}
3436
import scala.concurrent.ExecutionContext.Implicits.global
3537
import scala.concurrent.Future
@@ -46,23 +48,27 @@ val binding: Future[NettyFutureServerBinding] =
4648

4749
## Direct-style
4850

49-
The `tapir-netty-server-sync` server uses `Identity[T]` as its wrapper effect for compatibility; `Identity[A]` means in
51+
The `tapir-netty-server-sync` server uses `Identity[T]` as its wrapper effect for compatibility; `Identity[A]` means in
5052
fact just `A`, representing direct style. It is available only for Scala 3.
5153

52-
See [examples/helloWorldNettySyncServer.scala](https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/helloWorldNettySyncServer.scala) for a full example.
54+
See
55+
[examples/helloWorldNettySyncServer.scala](https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/helloWorldNettySyncServer.scala)
56+
for a full example.
5357

54-
To provide server logic for an endpoint when using the `-sync` server, you can use the dedicated `handle`
55-
methods, and its variants. This provides better type inference.
58+
To provide server logic for an endpoint when using the `-sync` server, you can use the dedicated `handle` methods, and
59+
its variants. This provides better type inference.
5660

5761
To learn more about handling concurrency with Ox, see the [documentation](https://ox.softwaremill.com/).
5862

5963
## Configuration
6064

61-
The interpreter can be configured by providing an `NettyFutureServerOptions` value, see [server options](options.md) for
65+
The interpreters can be configured by providing an `Netty[Sync|Future|...]ServerOptions` value, see [server
66+
options](options.md) for
6267
details.
6368

64-
Some options can be configured directly using a `NettyFutureServer` instance, such as the host and port. Others
65-
can be passed using the `NettyFutureServer(options)` methods. Options may also be overridden when adding endpoints.
69+
Some options can be configured directly using a `Netty[Sync|Future|...]Server` instance, such as the host and port.
70+
Others can be passed using the `Netty[Sync|Future|...]Server(options)` methods. Options may also be overridden when
71+
adding endpoints.
6672
For example:
6773

6874
```scala mdoc:compile-only
@@ -83,15 +89,37 @@ NettyFutureServer(NettyConfig.default.socketBacklog(256))
8389
Unlike other server interpreters, the Netty-based servers are by default configured to return a 404, in case none of
8490
the given endpoints match a request. This can be changed by using a different `RejectHandler`.
8591
86-
This is due to the fact that usually no other routes (not generated from endpoints) are added to a Netty server.
92+
This is due to the fact that usually no other routes (other than generated from Tapir's endpoints) are added to a Netty server.
93+
```
94+
95+
### Server socket configuration
96+
97+
`NettyConfig` exposes a number of configuration options which allows to customise the server socket, such as:
98+
* request timeout
99+
* connection timeout
100+
* linger timeout
101+
* graceful shutdown timeout: when stopped e.g. using `NettyFutureServerBinding.stop()`, it's ensured that the server
102+
will wait at most 10 seconds for in-flight requests to complete, while rejecting all new requests with 503 during this
103+
period; afterwards, all server resources are closed
104+
* server header
105+
* maximum number of connections
106+
* custom netty pipeline & low-level logging handlers
107+
108+
For example, to change the request timeout:
109+
110+
```scala mdoc:compile-only
111+
import sttp.tapir.server.netty.NettyConfig
112+
import scala.concurrent.duration.*
113+
114+
val config = NettyConfig.default.requestTimeout(5.seconds)
87115
```
88116

89117
## Web sockets
90118

91119
### tapir-netty-server-cats
92120

93-
The Cats Effects interpreter supports web sockets, with pipes of type `fs2.Pipe[F, REQ, RESP]`. See [web sockets](../endpoint/websockets.md)
94-
for more details.
121+
The Cats Effects interpreter supports web sockets, with pipes of type `fs2.Pipe[F, REQ, RESP]`. See [web
122+
sockets](../endpoint/websockets.md) for more details.
95123

96124
To create a web socket endpoint, use Tapir's `out(webSocketBody)` output type:
97125

@@ -155,8 +183,11 @@ object WebSocketsNettyCatsServer extends ResourceApp.Forever {
155183

156184
### tapir-netty-server-sync
157185

158-
In the Loom-based backend, Tapir uses [Ox](https://ox.softwaremill.com) to manage concurrency, and your transformation pipeline should be represented as `Flow[A] => Flow[B]`. Any forks started within this function will be run under a safely isolated internal scope.
159-
See [examples/websocket/WebSocketNettySyncServer.scala](https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/websocket/WebSocketNettySyncServer.scala) for a full example.
186+
In the Loom-based backend, Tapir uses [Ox](https://ox.softwaremill.com) to manage concurrency, and your transformation
187+
pipeline should be represented as `Flow[A] => Flow[B]`. Any forks started within this function will be run under a
188+
safely isolated internal scope. See
189+
[examples/websocket/WebSocketNettySyncServer.scala](https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/websocket/WebSocketNettySyncServer.scala)
190+
for a full example.
160191

161192
```{note}
162193
The pipeline transforms a source of incoming web socket messages (received from the client), into a source of outgoing web socket messages (which will be sent to the client), within some concurrency scope. Once the incoming source is done, the client has closed the connection. In that case, remember to close the outgoing source as well: otherwise the scope will leak and won't be closed. An error will be logged if the outgoing channel is not closed within a timeout after a close frame is received.
@@ -166,7 +197,8 @@ The pipeline transforms a source of incoming web socket messages (received from
166197

167198
### tapir-netty-server-sync
168199

169-
The interpreter supports [SSE (Server Sent Events)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).
200+
The interpreter supports [SSE (Server Sent
201+
Events)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events).
170202

171203
For example, to define an endpoint that returns event stream:
172204

@@ -189,21 +221,6 @@ val sseFlow = Flow
189221
val sseServerEndpoint = sseEndpoint.handleSuccess(_ => sseFlow)
190222
```
191223

192-
## Graceful shutdown
193-
194-
A Netty server can be gracefully closed using the function `NettyFutureServerBinding.stop()` (and analogous functions available in Cats and ZIO bindings). This function ensures that the server will wait at most 10 seconds for in-flight requests to complete, while rejecting all new requests with 503 during this period. Afterwards, it closes all server resources.
195-
You can customize this behavior in `NettyConfig`:
196-
197-
```scala mdoc:compile-only
198-
import sttp.tapir.server.netty.NettyConfig
199-
import scala.concurrent.duration.*
200-
201-
// adjust the waiting time to your needs
202-
val config = NettyConfig.default.withGracefulShutdownTimeout(5.seconds)
203-
// or if you don't want the server to wait for in-flight requests
204-
val config2 = NettyConfig.default.noGracefulShutdown
205-
```
206-
207224
## Domain socket support
208225

209226
There is possibility to use Domain socket instead of TCP for handling traffic.

0 commit comments

Comments
 (0)