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

AsyncApi schema - use of .withDiscriminator for Schema renders illegal async api spec #3754

Open
kamilkloch opened this issue May 8, 2024 · 1 comment

Comments

@kamilkloch
Copy link
Contributor

/** 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

@kamilkloch
Copy link
Contributor Author

Duplicate of #3275

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant