Skip to content

Commit

Permalink
Release 1.9.6
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw committed Dec 21, 2023
1 parent bf2cd21 commit cb3be88
Show file tree
Hide file tree
Showing 29 changed files with 150 additions and 76 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ tapir documentation is available at [tapir.softwaremill.com](http://tapir.softwa
Add the following dependency:

```sbt
"com.softwaremill.sttp.tapir" %% "tapir-core" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-core" % "1.9.6"
```

Then, import:
Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/client/http4s.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Add the dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-http4s-client" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-http4s-client" % "1.9.6"
```

To interpret an endpoint definition as an `org.http4s.Request[F]`, import:
Expand Down
4 changes: 2 additions & 2 deletions generated-doc/out/client/play.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ See the [Play framework documentation](https://www.playframework.com/documentati
For **Play 3.0**, add the dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-play-client" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-play-client" % "1.9.6"
```

For **Play 2.9**, add

```scala
"com.softwaremill.sttp.tapir" %% "tapir-play29-client" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-play29-client" % "1.9.6"
```

instead. Furthermore, replace all uses of `sttp.capabilities.pekko.PekkoStreams` in the following code snippets with `sttp.capabilities.akka.AkkaStreams`.
Expand Down
4 changes: 2 additions & 2 deletions generated-doc/out/client/sttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Add the dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-sttp-client" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-sttp-client" % "1.9.6"
```

To make requests using an endpoint definition using the [sttp client](https://github.com/softwaremill/sttp), import:
Expand Down Expand Up @@ -100,7 +100,7 @@ In this case add the following dependencies (note the [`%%%`](https://www.scala-
instead of the usual `%%`):

```scala
"com.softwaremill.sttp.tapir" %%% "tapir-sttp-client" % "1.9.5"
"com.softwaremill.sttp.tapir" %%% "tapir-sttp-client" % "1.9.6"
"io.github.cquiroz" %%% "scala-java-time" % "2.2.0" // implementations of java.time classes for Scala.JS
```

Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/docs/asyncapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
To use, add the following dependencies:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-asyncapi-docs" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-asyncapi-docs" % "1.9.6"
"com.softwaremill.sttp.apispec" %% "asyncapi-circe-yaml" % "..." // see https://github.com/softwaremill/sttp-apispec
```

Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/docs/json-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
You can conveniently generate JSON schema from Tapir schema, which can be derived from your Scala types. Use `TapirSchemaToJsonSchema`:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-apispec-docs" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-apispec-docs" % "1.9.6"
```

Schema generation can now be performed like in the following example:
Expand Down
12 changes: 6 additions & 6 deletions generated-doc/out/docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ these steps can be done separately, giving you complete control over the process
To generate OpenAPI documentation and expose it using the Swagger UI in a single step, first add the dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-bundle" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-bundle" % "1.9.6"
```

Then, you can interpret a list of endpoints using `SwaggerInterpreter`. The result will be a list of file-serving
Expand Down Expand Up @@ -55,7 +55,7 @@ for details.
Similarly as above, you'll need the following dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-redoc-bundle" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-redoc-bundle" % "1.9.6"
```

And the server endpoints can be generated using the `sttp.tapir.redoc.bundle.RedocInterpreter` class.
Expand All @@ -65,7 +65,7 @@ And the server endpoints can be generated using the `sttp.tapir.redoc.bundle.Red
To generate the docs in the OpenAPI yaml format, add the following dependencies:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % "1.9.6"
"com.softwaremill.sttp.apispec" %% "openapi-circe-yaml" % "..." // see https://github.com/softwaremill/sttp-apispec
```

Expand Down Expand Up @@ -133,7 +133,7 @@ For example, generating the OpenAPI 3.0.3 YAML string can be achieved by perform

Firstly add dependencies:
```scala
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % "1.9.6"
"com.softwaremill.sttp.apispec" %% "openapi-circe-yaml" % "..." // see https://github.com/softwaremill/sttp-apispec
```

Expand Down Expand Up @@ -163,12 +163,12 @@ The modules `tapir-swagger-ui` and `tapir-redoc` contain server endpoint definit
yaml format, will expose it using the given context path. To use, add as a dependency either
`tapir-swagger-ui`:
```scala
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui" % "1.9.6"
```

or `tapir-redoc`:
```scala
"com.softwaremill.sttp.tapir" %% "tapir-redoc" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-redoc" % "1.9.6"
```

Then, you'll need to pass the server endpoints to your server interpreter. For example, using akka-http:
Expand Down
92 changes: 83 additions & 9 deletions generated-doc/out/endpoint/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `tapir-cats` module contains additional instances for some [cats](https://ty
datatypes as well as additional syntax:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-cats" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-cats" % "1.9.6"
```

- `import sttp.tapir.integ.cats.codec._` - brings schema, validator and codec instances
Expand All @@ -24,7 +24,7 @@ Additionally, the `tapir-cats-effect` module contains an implementation of the `
between the sttp-internal `MonadError` and the cats-effect `Sync` typeclass:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-cats-effect" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-cats-effect" % "1.9.6"
```

## Refined integration
Expand All @@ -33,7 +33,7 @@ If you use [refined](https://github.com/fthomas/refined), the `tapir-refined` mo
validators for `T Refined P` as long as a codec for `T` already exists:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-refined" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-refined" % "1.9.6"
```

You'll need to extend the `sttp.tapir.codec.refined.TapirCodecRefined`
Expand All @@ -54,7 +54,7 @@ If you use [iron](https://github.com/Iltotore/iron), the `tapir-iron` module wil
validators for `T :| P` as long as a codec for `T` already exists:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-iron" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-iron" % "1.9.6"
```

The module is only available for Scala 3 since iron is not designed to work with Scala 2.
Expand All @@ -66,13 +66,87 @@ The iron codecs contain a validator which apply the constraint to validated valu

Similarly to `tapir-refined`, you can find the predicate logic in `integrations/iron/src/main/scala/sttp/iron/codec/iron/TapirCodecIron.scala` and provide your own given `ValidatorForPredicate[T, P]` in scope using `ValidatorForPredicate.fromPrimitiveValidator`

### Validation

When using `iron` in the server e.g. in case classes that JSON request body
is parsed to, some additional steps need to be taken to properly
report `iron` validation errors.

[Iron](https://github.com/Iltotore/iron) is operating on type level while regular tapir
validation works on case classes created from parsed JSON. When `iron` types are used
in a case class, and passed values are invalid for `iron` types, creation is impossible because `iron`
does not allow creating guarded type instance.
Because it is not possible to create case class for `ServerInterpreter` it looks like JSON parsing error not
like validation error. In such case no error message is displayed to user.

To properly report `iron` errors it is necessary to recognize them in failure intereptor.
Custom JSON parsing is necessary anyway so custom exception can be thrown in case of `iron`
refinement error and then matched in failure interceptor.

Example for `circe`:

```scala
case class IronException(error: String) extends Exception(error)

inline given (using inline constraint: Constraint[Int, Positive]): Decoder[Age] = summon[Decoder[Int]].map(unrefinedValue =>
unrefinedValue.refineEither[Positive] match
case Right(value) => value
case Left(errorMessage) => throw IronException(s"Could not refine value $unrefinedValue: $errorMessage")
)
```

Then failure handler matching `IronException` is needed. Remember to create the interceptor:

```scala
private def failureDetailMessage(failure: DecodeResult.Failure): Option[String] = failure match {
case Error(_, JsonDecodeException(_, IronException(errorMessage))) => Some(errorMessage)
case Error(_, IronException(errorMessage)) => Some(errorMessage)
case other => FailureMessages.failureDetailMessage(other)
}

private def failureMessage(ctx: DecodeFailureContext): String = {
val base = FailureMessages.failureSourceMessage(ctx.failingInput)
val detail = failureDetailMessage(ctx.failure)
FailureMessages.combineSourceAndDetail(base, detail)
}

def ironFailureHandler[T[_]] = new DefaultDecodeFailureHandler[T](
DefaultDecodeFailureHandler.respond,
failureMessage,
DefaultDecodeFailureHandler.failureResponse
)

def ironDecodeFailureInterceptor[T[_]] = new DecodeFailureInterceptor[T](ironFailureHandler[T])
```

...and add it to server options:

```scala
override def run = NettyCatsServer
.io()
.use { server =>
// Don't forget to add the interceptor to server options
val optionsWithInterceptor = server.options.prependInterceptor(ironDecodeFailureInterceptor)
for {
binding <- server
.port(port)
.host(host)
.options(optionsWithInterceptor)
.addEndpoint(endpoint)
.start()
//...
}
}
```


## Enumeratum integration

The `tapir-enumeratum` module provides schemas, validators and codecs for [Enumeratum](https://github.com/lloydmeta/enumeratum)
enumerations. To use, add the following dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-enumeratum" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-enumeratum" % "1.9.6"
```

Then, `import sttp.tapir.codec.enumeratum._`, or extends the `sttp.tapir.codec.enumeratum.TapirCodecEnumeratum` trait.
Expand All @@ -85,7 +159,7 @@ If you use [scala-newtype](https://github.com/estatico/scala-newtype), the `tapi
schemas for types with a `@newtype` and `@newsubtype` annotations as long as a codec and schema for its underlying value already exists:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-newtype" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-newtype" % "1.9.6"
```

Then, `import sttp.tapir.codec.newtype._`, or extend the `sttp.tapir.codec.newtype.TapirCodecNewType` trait to bring the implicit values into scope.
Expand All @@ -96,7 +170,7 @@ If you use [monix newtypes](https://github.com/monix/newtypes), the `tapir-monix
schemas for types which extend `NewtypeWrapped` and `NewsubtypeWrapped` annotations as long as a codec and schema for its underlying value already exists:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-monix-newtype" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-monix-newtype" % "1.9.6"
```

Then, `import sttp.tapir.codec.monix.newtype._`, or extend the `sttp.tapir.codec.monix.newtype.TapirCodecMonixNewType` trait to bring the implicit values into scope.
Expand All @@ -107,7 +181,7 @@ If you use [ZIO Prelude Newtypes](https://zio.github.io/zio-prelude/docs/newtype
schemas for types defined using `Newtype` and `Subtype` as long as a codec and a schema for the underlying type already exists:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-zio-prelude" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-zio-prelude" % "1.9.6"
```

Then, mix in `sttp.tapir.codec.zio.prelude.newtype.TapirNewtypeSupport` into your newtype to bring the implicit values into scope:
Expand Down Expand Up @@ -146,7 +220,7 @@ For details refer to [derevo documentation](https://github.com/tofu-tf/derevo#in
To use, add the following dependency:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-derevo" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-derevo" % "1.9.6"
```

Then you can derive schema for your ADT along with other typeclasses besides ADT declaration itself:
Expand Down
18 changes: 9 additions & 9 deletions generated-doc/out/endpoint/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ stringJsonBody.schema(implicitly[Schema[MyBody]].as[String])
To use [Circe](https://github.com/circe/circe), add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonCirce` trait, see [MyTapir](../mytapir.md)):
Expand Down Expand Up @@ -125,7 +125,7 @@ Now the above JSON object will render as
To use [µPickle](http://www.lihaoyi.com/upickle/) add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-upickle" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-upickle" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonuPickle` trait, see [MyTapir](../mytapir.md) and add `TapirJsonuPickle` not `TapirCirceJson`):
Expand Down Expand Up @@ -160,13 +160,13 @@ For more examples, including making a custom encoder/decoder, see [TapirJsonuPic
To use [Play JSON](https://github.com/playframework/play-json) for **Play 3.0**, add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-play" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-play" % "1.9.6"
```

For **Play 2.9** use:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-play29" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-play29" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonPlay` trait, see [MyTapir](../mytapir.md) and add `TapirJsonPlay` not `TapirCirceJson`):
Expand All @@ -182,7 +182,7 @@ Play JSON requires `Reads` and `Writes` implicit values in scope for each type y
To use [Spray JSON](https://github.com/spray/spray-json) add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-spray" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-spray" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonSpray` trait, see [MyTapir](../mytapir.md) and add `TapirJsonSpray` not `TapirCirceJson`):
Expand All @@ -198,7 +198,7 @@ Spray JSON requires a `JsonFormat` implicit value in scope for each type you wan
To use [Tethys JSON](https://github.com/tethys-json/tethys) add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-tethys" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-tethys" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonTethys` trait, see [MyTapir](../mytapir.md) and add `TapirJsonTethys` not `TapirCirceJson`):
Expand All @@ -214,7 +214,7 @@ Tethys JSON requires `JsonReader` and `JsonWriter` implicit values in scope for
To use [Jsoniter-scala](https://github.com/plokhotnyuk/jsoniter-scala) add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-jsoniter-scala" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-jsoniter-scala" % "1.9.6"
```

Next, import the package (or extend the `TapirJsonJsoniter` trait, see [MyTapir](../mytapir.md) and add `TapirJsonJsoniter` not `TapirCirceJson`):
Expand All @@ -230,7 +230,7 @@ Jsoniter Scala requires `JsonValueCodec` implicit value in scope for each type y
To use [json4s](https://github.com/json4s/json4s) add the following dependencies to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-json4s" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-json4s" % "1.9.6"
```

And one of the implementations:
Expand Down Expand Up @@ -261,7 +261,7 @@ implicit val formats: Formats = org.json4s.jackson.Serialization.formats(NoTypeH
To use [zio-json](https://github.com/zio/zio-json), add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-zio" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-zio" % "1.9.6"
```
Next, import the package (or extend the `TapirJsonZio` trait, see [MyTapir](../mytapir.md) and add `TapirJsonZio` instead of `TapirCirceJson`):

Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/endpoint/pickler.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ In [other](json.md) tapir-JSON integrations, you have to keep the `Schema` (whic
To use pickler, add the following dependency to your project:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-json-pickler" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-json-pickler" % "1.9.6"
```

Please note that it is available only for Scala 3 and Scala.JS 3.
Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/endpoint/static.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ from local files or application resources. These endpoints respect etags, byte r
In order to use static content endpoints, add the module to your dependencies:

```scala
"com.softwaremill.sttp.tapir" %% "tapir-files" % "1.9.5"
"com.softwaremill.sttp.tapir" %% "tapir-files" % "1.9.6"
```

## Files
Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/examples.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Examples

The [examples](https://github.com/softwaremill/tapir/tree/master/examples/src/main/scala/sttp/tapir/examples) and [examples3](https://github.com/softwaremill/tapir/tree/master/examples3/src/main/scala/sttp/tapir/examples3) sub-projects (the latter containing Scala 3-only code) contains a number of runnable tapir usage examples, using various interpreters and showcasing different features.
The [examples](https://github.com/softwaremill/tapir/tree/master/examples/src/main/scala/sttp/tapir/examples) and [examples2](https://github.com/softwaremill/tapir/tree/master/examples2/src/main/scala/sttp/tapir/examples2) sub-projects (the latter containing Scala 2-only code) contains a number of runnable tapir usage examples, using various interpreters and showcasing different features.

## Generate a tapir project

Expand Down
2 changes: 1 addition & 1 deletion generated-doc/out/generator/sbt-openapi-codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Add the sbt plugin to the `project/plugins.sbt`:

```scala
addSbtPlugin("com.softwaremill.sttp.tapir" % "sbt-openapi-codegen" % "1.9.5")
addSbtPlugin("com.softwaremill.sttp.tapir" % "sbt-openapi-codegen" % "1.9.6")
```

Enable the plugin for your project in the `build.sbt`:
Expand Down

0 comments on commit cb3be88

Please sign in to comment.