softwaremill / softwaremill/tapir
[BUG] AsyncAPI generated schema issue when using Configuration.withDiscriminator
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 1.5k
- Forks
- 468
- Avg merge
- 5h 37m
- Merged PRs (30d)
- 34
Description
Tapir version: 1.8.2
Scala version: 3.3.1
AsyncAPI studio can't parse the generated yaml when using Configuration.default.withDiscriminator for ADT type or simple enum.
Given this minimal example
//> using dep com.softwaremill.sttp.tapir::tapir-zio-http-server:1.8.2
//> using dep com.softwaremill.sttp.tapir::tapir-asyncapi-docs:1.8.2
//> using dep com.softwaremill.sttp.apispec::asyncapi-circe-yaml:0.7.1
//> using dep com.softwaremill.sttp.tapir::tapir-jsoniter-scala:1.8.2
//> using dep "com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:2.24.2"
import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker
import sttp.apispec.asyncapi.circe.yaml.*
import sttp.capabilities.zio.ZioStreams
import sttp.tapir.Schema
import sttp.tapir.*
import sttp.tapir.docs.asyncapi.AsyncAPIInterpreter
import sttp.tapir.generic.Configuration
import sttp.tapir.generic.auto.*
import sttp.tapir.json.jsoniter.*
object TapirADT extends App:
val end = endpoint.in("test").out(webSocketBody[Topic, CodecFormat.Json, Topic, CodecFormat.Json](ZioStreams))
val api = AsyncAPIInterpreter().toAsyncAPI(end, "Websocket", "1.0").toYaml
println(api)
sealed trait Topic
object Topic:
sealed trait PublicTopic extends Topic
sealed trait PrivateTopic extends Topic
case object PublicParts extends PublicTopic
case object PrivateParts extends PrivateTopic
given JsonValueCodec[Topic] = JsonCodecMaker.make
given Schema[Topic] = {
given Configuration = Configuration.default.withDiscriminator("type")
Schema.derived[Topic]
}
Which generates this yaml
info:
title: Websocket
version: '1.0'
channels:
/test:
subscribe:
operationId: onTest
message:
$ref: '#/components/messages/Topic'
publish:
operationId: sendTest
message:
$ref: '#/components/messages/Topic'
bindings:
ws:
method: GET
components:
schemas:
Topic:
oneOf:
- $ref: '#/components/schemas/PrivateParts'
- $ref: '#/components/schemas/PublicParts'
discriminator:
propertyName: type
mapping:
PrivateParts: '#/components/schemas/PrivateParts'
PublicParts: '#/components/schemas/PublicParts'
PrivateParts:
required:
- type
type: object
properties:
type:
type: string
PublicParts:
required:
- type
type: object
properties:
type:
type: string
messages:
Topic:
payload:
$ref: '#/components/schemas/Topic'
contentType: application/json
You can see in the attached screenshot that AsyncAPI studio can't parse the generated yaml. The equivalent of this with simple (non websocket) endpoint for OpenAPI works fine while using Configuration.default.withDiscriminator.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the supplied Scala 3.3.1 reproduction with AsyncAPIInterpreter().toAsyncAPI and inspect the generated YAML around the discriminator schema. Compare the AsyncAPI output with the working OpenAPI behavior and verify the result in AsyncAPI Studio. Done means the generated YAML parses successfully while discriminator support for ADTs and simple enums remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100