Skip to content

Instantly share code, notes, and snippets.

@susliko
Last active April 18, 2024 15:02
Show Gist options
  • Save susliko/4378a93a66b04cb9b6656d109792f2ed to your computer and use it in GitHub Desktop.
Save susliko/4378a93a66b04cb9b6656d109792f2ed to your computer and use it in GitHub Desktop.
//> using scala 3.3.1
//> using dep com.softwaremill.sttp.tapir::tapir-core:1.10.3
//> using dep com.softwaremill.sttp.tapir::tapir-json-circe:1.10.3
//> using dep com.softwaremill.sttp.tapir::tapir-openapi-docs:1.10.3
//> using dep com.softwaremill.sttp.tapir::tapir-jdkhttp-server:1.10.3
//> using dep com.softwaremill.sttp.apispec::openapi-circe-yaml::0.8.0
//> using dep com.softwaremill.sttp.apispec::openapi-circe-yaml::0.8.0
import sttp.tapir.*
import sttp.tapir.json.circe.*
import io.circe.*
import sttp.model.*
import sttp.tapir.docs.openapi.*
import sttp.apispec.openapi.*
import sttp.apispec.openapi.circe.yaml.*
import sttp.tapir.server.jdkhttp.*
import java.net.InetSocketAddress
import scala.util.Random
sealed trait A
case class B(b: String) extends A derives Schema, Encoder.AsObject, Decoder
case class C(c: String) extends A derives Schema, Encoder.AsObject, Decoder
case class D(d: String) extends A derives Schema, Encoder.AsObject, Decoder
@main
def tapirOneOf =
val myEndpoint = endpoint.get
.in("path")
.out(
oneOf[A](
oneOfVariant(statusCode(StatusCode.Ok).and(jsonBody[B])),
oneOfVariant(statusCode(StatusCode.Ok).and(jsonBody[C])),
oneOfVariant(statusCode(StatusCode.Accepted).and(jsonBody[D]))
)
)
.handle(_ => Right(Random.shuffle(List[A](B(""), C(""), D(""))).head))
val docs: OpenAPI =
OpenAPIDocsInterpreter().toOpenAPI(myEndpoint, "My Service", "1.0")
println(docs.toYaml)
val server: HttpServer =
JdkHttpServer().port(8082).addEndpoint(myEndpoint).start()
/*
`curl -v localhost:8080/path` can result both in B and C in case of 200 code, but the schema declares only C
Schema output:
openapi: 3.1.0
info:
title: My Service
version: '1.0'
paths:
/path:
get:
operationId: getPath
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/C'
'202':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/D'
components:
schemas:
B:
title: B
required:
- b
type: object
properties:
b:
type: string
C:
title: C
required:
- c
type: object
properties:
c:
type: string
D:
title: D
required:
- d
type: object
properties:
d:
type: string
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment