Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change akka to netty in exmaples in docs #2957

Merged
merged 4 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions doc/docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interpreter. For example:
```scala mdoc:compile-only
import sttp.tapir._
import sttp.tapir.swagger.bundle.SwaggerInterpreter
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import sttp.tapir.server.netty.{NettyFutureServerInterpreter, FutureRoute}

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
Expand All @@ -35,7 +35,7 @@ val myEndpoints: List[AnyEndpoint] = ???
val swaggerEndpoints = SwaggerInterpreter().fromEndpoints[Future](myEndpoints, "My App", "1.0")

// add to your akka routes
val swaggerRoute = AkkaHttpServerInterpreter().toRoute(swaggerEndpoints)
val swaggerRoute: FutureRoute = NettyFutureServerInterpreter().toRoute(swaggerEndpoints)
```

By default, the documentation will be available under the `/docs` path. The path, as well as other options can be
Expand Down Expand Up @@ -182,7 +182,7 @@ Then, you'll need to pass the server endpoints to your server interpreter. For e
import sttp.apispec.openapi.circe.yaml._
import sttp.tapir._
import sttp.tapir.docs.openapi.OpenAPIDocsInterpreter
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import sttp.tapir.server.netty.{NettyFutureServerInterpreter, FutureRoute}
import sttp.tapir.swagger.SwaggerUI

import scala.concurrent.Future
Expand All @@ -192,7 +192,7 @@ val myEndpoints: Seq[AnyEndpoint] = ???
val docsAsYaml: String = OpenAPIDocsInterpreter().toOpenAPI(myEndpoints, "My App", "1.0").toYaml

// add to your akka routes
PanHNE marked this conversation as resolved.
Show resolved Hide resolved
val swaggerUIRoute = AkkaHttpServerInterpreter().toRoute(SwaggerUI[Future](docsAsYaml))
val swaggerUIRoute: FutureRoute = NettyFutureServerInterpreter().toRoute(SwaggerUI[Future](docsAsYaml))
```

## Options
Expand Down
10 changes: 5 additions & 5 deletions doc/server/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ For example:

```scala mdoc:compile-only
import sttp.tapir._
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import sttp.tapir.server.netty.NettyFutureServerInterpreter
import scala.concurrent.Future
import scala.util._

Expand All @@ -38,7 +38,7 @@ def handleErrors[T](f: Future[T]): Future[Either[ErrorInfo, T]] =
Success(Left(e.getMessage))
}

AkkaHttpServerInterpreter().toRoute(
NettyFutureServerInterpreter().toRoute(
endpoint
.errorOut(plainBody[ErrorInfo])
.out(plainBody[Int])
Expand Down Expand Up @@ -153,17 +153,17 @@ We'll need to provide both the endpoint output which should be used for error me
```scala mdoc:compile-only
import sttp.tapir._
import sttp.tapir.server.model.ValuedEndpointOutput
import sttp.tapir.server.akkahttp.AkkaHttpServerOptions
import sttp.tapir.server.netty.NettyFutureServerOptions
import java.net.InetSocketAddress
import sttp.tapir.generic.auto._
import sttp.tapir.json.circe._
import io.circe.generic.auto._
import scala.concurrent.ExecutionContext.Implicits.global

case class MyFailure(msg: String)
def myFailureResponse(m: String): ValuedEndpointOutput[_] =
ValuedEndpointOutput(jsonBody[MyFailure], MyFailure(m))

val myServerOptions: AkkaHttpServerOptions = AkkaHttpServerOptions
val myServerOptions: NettyFutureServerOptions[InetSocketAddress] = NettyFutureServerOptions
.customiseInterceptors
.defaultHandlers(myFailureResponse)
.options
Expand Down
7 changes: 3 additions & 4 deletions doc/server/logic.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,21 @@ val aServerEndpoint: ServerEndpoint[Any, Future] = anEndpoint.serverLogic((logic
## Interpreting as a server

Both a single server endpoint, and multiple endpoints can be interpreted as a server. As an example, a list of server
endpoints can be converted to an akka-http route:
endpoints can be converted to an Netty route:
PanHNE marked this conversation as resolved.
Show resolved Hide resolved

```scala mdoc:compile-only
import sttp.tapir._
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import sttp.tapir.server.netty.{NettyFutureServerInterpreter, FutureRoute}
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import akka.http.scaladsl.server.Route

val endpoint1 = endpoint.in("hello").out(stringBody)
.serverLogic { _ => Future.successful[Either[Unit, String]](Right("world")) }

val endpoint2 = endpoint.in("ping").out(stringBody)
.serverLogic { _ => Future.successful[Either[Unit, String]](Right("pong")) }

val route: Route = AkkaHttpServerInterpreter().toRoute(List(endpoint1, endpoint2))
val route: FutureRoute = NettyFutureServerInterpreter().toRoute(List(endpoint1, endpoint2))
```

## Recovering errors from failed effects
Expand Down
11 changes: 5 additions & 6 deletions doc/server/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,12 @@ Add the following dependency:
`PrometheusMetrics` encapsulates `CollectorReqistry` and `Metric` instances. It provides several ready to use metrics as
well as an endpoint definition to read the metrics & expose them to the Prometheus server.

For example, using `AkkaServerInterpeter`:
For example, using `NettyFutureServerInterpreter`:

```scala mdoc:compile-only
import akka.http.scaladsl.server.Route
import io.prometheus.client.CollectorRegistry
import sttp.tapir.server.metrics.prometheus.PrometheusMetrics
import sttp.tapir.server.akkahttp.{AkkaHttpServerInterpreter, AkkaHttpServerOptions}
import sttp.tapir.server.netty.{NettyFutureServerInterpreter, NettyFutureServerOptions, FutureRoute}
import java.net.InetSocketAddress

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
Expand All @@ -70,13 +69,13 @@ import scala.concurrent.ExecutionContext.Implicits.global
val prometheusMetrics = PrometheusMetrics.default[Future]()

// enable metrics collection
val serverOptions: AkkaHttpServerOptions = AkkaHttpServerOptions
val serverOptions: NettyFutureServerOptions[InetSocketAddress] = NettyFutureServerOptions
.customiseInterceptors
.metricsInterceptor(prometheusMetrics.metricsInterceptor())
.options

// route which exposes the current metrics values
val routes: Route = AkkaHttpServerInterpreter(serverOptions).toRoute(prometheusMetrics.metricsEndpoint)
val routes: FutureRoute = NettyFutureServerInterpreter(serverOptions).toRoute(prometheusMetrics.metricsEndpoint)
```

By default, the following metrics are exposed:
Expand Down
4 changes: 1 addition & 3 deletions generated-doc/out/server/akkahttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,4 @@ val routes = AkkaHttpServerInterpreter().toRoute(sseEndpoint.serverLogicSuccess[
```

## Configuration

PanHNE marked this conversation as resolved.
Show resolved Hide resolved
The interpreter can be configured by providing an `AkkaHttpServerOptions` value, see
[server options](options.md) for details.
The interpreter can be configured by providing an `AkkaHttpServerOptions` value.
26 changes: 12 additions & 14 deletions generated-doc/out/server/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ Each interpreter can be configured using an options object, which includes:
* additional user-provided [interceptors](interceptors.md)

To use custom server options pass them as an argument to the interpreter's `apply` method.
For example, for `AkkaHttpServerOptions` and `AkkaHttpServerInterpreter`:
For example, for `NettyFutureServerOptions` and `NettyFutureServerInterpreter`:

```scala
import sttp.tapir.server.interceptor.decodefailure.DecodeFailureHandler
import sttp.tapir.server.akkahttp.AkkaHttpServerOptions
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import scala.concurrent.ExecutionContext.Implicits.global
import sttp.tapir.server.netty.{NettyFutureServerOptions, NettyFutureServerInterpreter}
import java.net.InetSocketAddress

val customDecodeFailureHandler: DecodeFailureHandler = ???

val customServerOptions: AkkaHttpServerOptions = AkkaHttpServerOptions
val customServerOptions: NettyFutureServerOptions[InetSocketAddress] = NettyFutureServerOptions
.customiseInterceptors
.decodeFailureHandler(customDecodeFailureHandler)
.options
AkkaHttpServerInterpreter(customServerOptions)

NettyFutureServerInterpreter(customServerOptions)
```

## Hiding authenticated endpoints
Expand All @@ -34,20 +33,19 @@ By default, if authentication credentials are missing for an endpoint which defi
a `401 Unauthorized` response is returned.

If you would instead prefer to hide the fact that such an endpoint exists from the client, a `404 Not Found` can be
returned instead by using a different decode failure handler. For example, using akka-http:
returned instead by using a different decode failure handler. For example, using Netty:

```scala
import sttp.tapir.server.interceptor.decodefailure.DefaultDecodeFailureHandler
import sttp.tapir.server.akkahttp.AkkaHttpServerOptions
import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter
import scala.concurrent.ExecutionContext.Implicits.global
import sttp.tapir.server.netty.{NettyFutureServerOptions, NettyFutureServerInterpreter}
import java.net.InetSocketAddress

val customServerOptions: AkkaHttpServerOptions = AkkaHttpServerOptions
val customServerOptions: NettyFutureServerOptions[InetSocketAddress] = NettyFutureServerOptions
.customiseInterceptors
.decodeFailureHandler(DefaultDecodeFailureHandler.hideEndpointsWithAuth)
.options
AkkaHttpServerInterpreter(customServerOptions)

NettyFutureServerInterpreter(customServerOptions)
```

Note however, that it can still be possible to discover the existence of certain endpoints using timing attacks.
Expand Down
20 changes: 11 additions & 9 deletions generated-doc/out/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,26 @@ Custom interpreters can be provided to the stub. For example, to test custom exc
following customised akka http options:

```scala
import sttp.tapir._
import scala.concurrent.Future
import sttp.tapir.server.interceptor.exception.ExceptionHandler
import sttp.tapir.server.interceptor.CustomiseInterceptors
import sttp.tapir.server.akkahttp.AkkaHttpServerOptions
import sttp.tapir.server.model.ValuedEndpointOutput
import sttp.tapir.server.netty.NettyFutureServerOptions
import java.net.InetSocketAddress
import sttp.model.StatusCode

val exceptionHandler = ExceptionHandler.pure[Future](ctx =>
Some(ValuedEndpointOutput(
stringBody.and(statusCode),
(s"failed due to ${ctx.e.getMessage}", StatusCode.InternalServerError)
))
Some(ValuedEndpointOutput(
stringBody.and(statusCode),
(s"failed due to ${ctx.e.getMessage}", StatusCode.InternalServerError)
))
)

val customOptions: CustomiseInterceptors[Future, AkkaHttpServerOptions] = {
import scala.concurrent.ExecutionContext.Implicits.global
AkkaHttpServerOptions.customiseInterceptors
val customOptions: CustomiseInterceptors[Future, NettyFutureServerOptions[InetSocketAddress]] = {
NettyFutureServerOptions.customiseInterceptors
.exceptionHandler(exceptionHandler)
}
}
```

Testing such an interceptor requires simulating an exception being thrown in the server logic:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import scala.concurrent.{ExecutionContext, Future}
trait NettyFutureServerInterpreter {
def nettyServerOptions: NettyFutureServerOptions[_]

def toRoute(se: ServerEndpoint[Any, Future])(implicit ec: ExecutionContext): FutureRoute = {
toRoute(List(se))
}

def toRoute(
ses: List[ServerEndpoint[Any, Future]]
)(implicit ec: ExecutionContext): FutureRoute = {
Expand Down