Skip to content

Commit

Permalink
#91: docs
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw committed Oct 21, 2020
1 parent 9171bdd commit 1733b08
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 18 deletions.
12 changes: 8 additions & 4 deletions core/src/main/scala/sttp/tapir/EndpointIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -534,23 +534,27 @@ case class WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S](
def concatenateFragmentedFrames(c: Boolean): WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S] =
this.copy(concatenateFragmentedFrames = c)

/** @param i If `true`, [[WebSocketFrame.Pong]] frames will be ignored and won't be passed to the codecs for decoding.
/** Note: some interpreters ignore this setting.
* @param i If `true`, [[WebSocketFrame.Pong]] frames will be ignored and won't be passed to the codecs for decoding.
* Note that only some interpreters expose ping-pong frames.
*/
def ignorePong(i: Boolean): WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S] = this.copy(concatenateFragmentedFrames = i)

/** @param a If `true`, [[WebSocketFrame.Ping]] frames will cause a matching [[WebSocketFrame.Pong]] frame to be sent
/** Note: some interpreters ignore this setting.
* @param a If `true`, [[WebSocketFrame.Ping]] frames will cause a matching [[WebSocketFrame.Pong]] frame to be sent
* back, and won't be passed to codecs for decoding.
* Note that only some interpreters expose ping-pong frames.
*/
def autoPongOnPing(a: Boolean): WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S] = this.copy(concatenateFragmentedFrames = a)

/** @param d If `true`, [[WebSocketFrame.Close]] frames won't be passed to the request codec for decoding (in server
/** Note: some interpreters ignore this setting.
* @param d If `true`, [[WebSocketFrame.Close]] frames won't be passed to the request codec for decoding (in server
* interpreters).
*/
def decodeCloseRequests(d: Boolean): WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S] = this.copy(decodeCloseRequests = d)

/** @param d If `true`, [[WebSocketFrame.Close]] frames won't be passed to the response codec for decoding (in client
/** Note: some interpreters ignore this setting.
* @param d If `true`, [[WebSocketFrame.Close]] frames won't be passed to the response codec for decoding (in client
* interpreters).
*/
def decodeCloseResponses(d: Boolean): WebSocketBodyOutput[PIPE_REQ_RESP, REQ, RESP, T, S] = this.copy(decodeCloseResponses = d)
Expand Down
4 changes: 3 additions & 1 deletion doc/endpoint/websockets.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ Request/response schemas can be customised through `.requestsSchema` and `.respo
## Interpreting as a sever

When interpreting a web socket endpoint as a server, the [server logic](../server/logic.md) needs to provide a
streaming-specific pipe from requests to responses. E.g. in Akka's case, this will be `Flow[REQ, RESP, Any]`.
streaming-specific pipe from requests to responses. E.g. in akka's case, this will be `Flow[REQ, RESP, Any]`.

Refer to the documentation of interpreters for more details, as not all interpreters support all settings.

## Interpreting as a client

Expand Down
5 changes: 3 additions & 2 deletions doc/server/akkahttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ The capability can be added to the classpath independently of the interpreter th
The interpreter supports web sockets, with pipes of type `Flow[REQ, RESP, Any]`. See [web sockets](../endpoint/websockets.md)
for more details.

[Automatic pings](https://doc.akka.io/docs/akka-http/current/server-side/websocket-support.html#automatic-keep-alive-ping-support)
can be enabled through configuration.
akka-http does not expose control frames (`Ping`, `Pong` and `Close`), so any setting regarding them are discarded, and
ping/pong frames which are sent explicitly are ignored. [Automatic pings](https://doc.akka.io/docs/akka-http/current/server-side/websocket-support.html#automatic-keep-alive-ping-support)
can be instead enabled through configuration.

## Configuration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,30 @@ import scala.concurrent.{Await, Future}
object WebSocketAkkaServer extends App {
case class Response(hello: String)

// The endpoint: GET /ping.
// The web socket endpoint: GET /ping.
// We need to provide both the type & media type for the requests, and responses. Here, the requests will be
// strings, and responses will be returned as json.
val wsEndpoint: Endpoint[Unit, Unit, Flow[String, Response, Any], AkkaStreams with WebSockets] =
endpoint.get.in("ping").out(webSocketBody[String, CodecFormat.TextPlain, Response, CodecFormat.Json](AkkaStreams))

// Implementation of the web socket: a flow which echoes incoming messages
val wsRoute: Route = wsEndpoint.toRoute(_ => Future.successful(Right(Flow.fromFunction((in: String) => Response(in)))))

// documentation
// Documentation
val apiDocs = wsEndpoint.toAsyncAPI("JSON echo", "1.0", List("dev" -> Server("localhost:8080", "ws"))).toYaml
println(s"Paste into https://playground.asyncapi.io/ to see the docs for this endpoint:\n$apiDocs")

// starting the server
// Starting the server
implicit val actorSystem: ActorSystem = ActorSystem()
import actorSystem.dispatcher

val bindAndCheck = Http()
.newServerAt("localhost", 8080)
.bindFlow(wsRoute)
.flatMap { _ =>
// we could have interpreted wsEndpoint as a client, but here we are using sttp client directly
// We could have interpreted wsEndpoint as a client, but here we are using sttp client directly
val backend: SttpBackend[Future, WebSockets] = AkkaHttpBackend.usingActorSystem(actorSystem)
// Client which interacts with the web socket
basicRequest
.response(asWebSocket { ws: WebSocket[Future] =>
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ object WebSocketHttp4sServer extends App {

case class CountResponse(received: Int)

// The endpoint: GET /count.
// The web socket endpoint: GET /count.
// We need to provide both the type & media type for the requests, and responses. Here, the requests will be
// byte arrays, and responses will be returned as json.
val wsEndpoint: Endpoint[Unit, Unit, Pipe[IO, String, CountResponse], Fs2Streams[IO] with WebSockets] =
endpoint.get.in("count").out(webSocketBody[String, CodecFormat.TextPlain, CountResponse, CodecFormat.Json](Fs2Streams[IO]))

// counts the number of bytes received each second
// A pipe which counts the number of bytes received each second
val countBytes: Pipe[IO, String, CountResponse] = { in =>
sealed trait CountAction
case class AddAction(n: Int) extends CountAction
Expand All @@ -65,19 +65,21 @@ object WebSocketHttp4sServer extends App {
}
}

// implementing the endpoint's logic
// Implementing the endpoint's logic, by providing the web socket pipe
val wsRoutes: HttpRoutes[IO] = wsEndpoint.toRoutes(_ => IO.pure(Right(countBytes)))

// Documentation
val apiDocs = wsEndpoint.toAsyncAPI("Byte counter", "1.0", List("dev" -> Server("localhost:8080", "ws"))).toYaml
println(s"Paste into https://playground.asyncapi.io/ to see the docs for this endpoint:\n$apiDocs")

// starting the server
// Starting the server
BlazeServerBuilder[IO](ec)
.bindHttp(8080, "localhost")
.withHttpApp(Router("/" -> wsRoutes).orNotFound)
.resource
.flatMap(_ => AsyncHttpClientFs2Backend.resource[IO](blocker))
.use { backend =>
// Client which interacts with the web socket
basicRequest
.response(asWebSocket { ws: WebSocket[IO] =>
for {
Expand Down
4 changes: 3 additions & 1 deletion generated-doc/out/endpoint/websockets.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ Request/response schemas can be customised through `.requestsSchema` and `.respo
## Interpreting as a sever

When interpreting a web socket endpoint as a server, the [server logic](../server/logic.md) needs to provide a
streaming-specific pipe from requests to responses. E.g. in Akka's case, this will be `Flow[REQ, RESP, Any]`.
streaming-specific pipe from requests to responses. E.g. in akka's case, this will be `Flow[REQ, RESP, Any]`.

Refer to the documentation of interpreters for more details, as not all interpreters support all settings.

## Interpreting as a client

Expand Down
5 changes: 3 additions & 2 deletions generated-doc/out/server/akkahttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ The capability can be added to the classpath independently of the interpreter th
The interpreter supports web sockets, with pipes of type `Flow[REQ, RESP, Any]`. See [web sockets](../endpoint/websockets.md)
for more details.

[Automatic pings](https://doc.akka.io/docs/akka-http/current/server-side/websocket-support.html#automatic-keep-alive-ping-support)
can be enabled through configuration.
akka-http does not expose control frames (`Ping`, `Pong` and `Close`), so any setting regarding them are discarded, and
ping/pong frames which are sent explicitly are ignored. [Automatic pings](https://doc.akka.io/docs/akka-http/current/server-side/websocket-support.html#automatic-keep-alive-ping-support)
can be instead enabled through configuration.

## Configuration

Expand Down

0 comments on commit 1733b08

Please sign in to comment.