softwaremill / softwaremill/tapir
AsyncApi schema - use of `.withDiscriminator` for `Schema` renders illegal async api spec
Open
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 1.5k
- Forks
- 468
- Avg merge
- 5h 37m
- Merged PRs (30d)
- 34
Description
/** Use of discriminator, resulting yaml does not validate. Problematic part:
* ```
* discriminator:
* propertyName: fruit
* mapping:
* Apple: '#/components/schemas/Apple'
* Potato: '#/components/schemas/Potato'
* ```
*
* It should explicitly provide discriminator values using `const` override.
* ```
* Fruit:
* title: Fruit
* oneOf:
* - $ref: '#/components/schemas/Apple'
* - $ref: '#/components/schemas/Potato'
* discriminator: fruit
* Apple:
* title: Apple
* type: object
* required:
* - color
* - fruit
* properties:
* color:
* type: string
* fruit:
* type: string
* const: Apple
* ```
*
* Also note `sttp.tapir.Schema` lacks `const: Option[T]` property which would be needed to represent such schemas.
*/
object AsyncApiExample2 {
sttp.tapir.Schema
sealed trait Fruit
object Fruit {
case class Apple(color: String) extends Fruit
case class Potato(weight: Double) extends Fruit
private implicit val circeConfig: Configuration = Configuration.default.withDiscriminator("fruit")
implicit val fruitCodec: io.circe.Codec[Fruit] = deriveConfiguredCodec
private implicit val tapirConfig = sttp.tapir.generic.Configuration.default.withDiscriminator("fruit")
implicit val fruitSchema: sttp.tapir.Schema[Fruit] = sttp.tapir.Schema.derived
}
val ws = endpoint.get
.in("ws")
.out(
webSocketBody[Fruit, CodecFormat.Json, Fruit, CodecFormat.Json](Fs2Streams[IO])
.responsesExample(Fruit.Apple("red"))
.responsesExample(Fruit.Potato(1.0))
)
// print raw jsonschema for Fruit
val jsonSchema = TapirSchemaToJsonSchema(Fruit.fruitSchema, markOptionsAsNullable = true, metaSchema = MetaSchemaDraft04)
import sttp.apispec.circe._
println(jsonSchema.asJson.deepDropNullValues)
// print async api
val asyncApiYaml = AsyncAPIInterpreter()
.toAsyncAPI(ws, "web socket", "1.0")
.toYaml
def main(args: Array[String]): Unit = println(asyncApiYaml)
}
Repo with code: https://github.com/kamilkloch/tapir-async-api/blob/master/src/main/scala/AsyncApiExample2.scala
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
Start with AsyncApiExample2.scala in the linked reproduction repository, then trace how sttp.tapir.Schema.derived and AsyncAPIInterpreter generate the Fruit schema. Confirm the generated AsyncAPI is invalid without explicit discriminator values, and use the raw JSON Schema and YAML output to verify the resulting schema validates with the required const information.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100