Skip to content

const keyword does not exist in OpenAPI 3.0.3 and needs to be replaced by enum #241

@BITespresso

Description

@BITespresso

Using Tapir to generate the OpenAPI 3.0.3 specification for coproducts with a discriminator field, the value of the discriminator value for the coproducts has the type const in the OpenAPI 3.0.3 specification.

Unfortunately const was introduced in OpenAPI 3.1 and does not exist in OpenAPI 3.0.3. What needs to be done for OpenAPI 3.0.3 is to use a single enum value instead (see https://www.speakeasy.com/openapi/schemas/enums#constants-for-single-value-enums).

I prepared a REPL do demonstrate this:

scala-cli -S 3.6.4 \
  --dep com.softwaremill.sttp.apispec::jsonschema-circe:0.11.9 \
  --dep com.softwaremill.sttp.apispec::openapi-circe:0.11.9 \
  --dep com.softwaremill.sttp.tapir::tapir-apispec-docs:1.11.28

when running

import io.circe.Codec as CirceCodec
import io.circe.derivation.Configuration as CirceConfiguration
import io.circe.syntax.*
import sttp.apispec.circe.*
import sttp.tapir.docs.apispec.schema.TapirSchemaToJsonSchema
import sttp.tapir.generic.Configuration
import sttp.tapir.*

sealed trait Entity
case class Person(firstname: String, lastname: String) extends Entity
case class Organization(name: String) extends Entity

val discriminatorFieldName = "kind"

given Configuration = Configuration.default.withDiscriminator(discriminatorFieldName)
given CirceConfiguration = CirceConfiguration.default.withDiscriminator(discriminatorFieldName)

given CirceCodec[Entity] = CirceCodec.AsObject.derivedConfigured
given Schema[Entity] = Schema.derived

import sttp.apispec.openapi
import sttp.apispec.openapi.circe_openapi_3_0_3._

TapirSchemaToJsonSchema(summon[Schema[Entity]], markOptionsAsNullable = true).asJson

the resulting JSON contains a const value in the discriminator field:

  "$defs" : {
    "Organization" : {
      "title" : "Organization",
      "type" : "object",
      "required" : [
        "name",
        "kind"
      ],
      "properties" : {
        "name" : {
          "type" : "string"
        },
        "kind" : {
          "type" : "string",
          "const" : "Organization"
        }
      }
    }

However the expected result for OpenAPI 3.0.3 would be:

  "$defs" : {
    "Organization" : {
      "title" : "Organization",
      "type" : "object",
      "required" : [
        "name",
        "kind"
      ],
      "properties" : {
        "name" : {
          "type" : "string"
        },
        "kind" : {
          "type" : "string",
          "enum": ["Organization"]
        }
      }
    }

I'll submit a PR which fixes this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions