softwaremill / softwaremill/tapir
[BUG] Enumeration schema is inconsistent depending on the encoding function
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.10.10
Scala version: 2.13/3.3.3
I am deriving apispec.Schema from tapir.Schema for an enumeration and found that the default encode function produces inconsistent apispec.Schemas. Such inconsistency is exposed when apispec.Schema is encoded and decoded to/form json.
This problem is highlighted with the following code
Given following sealed trait
sealed trait Gender
case object Female extends Gender
case object Male extends Gender
with helper methods
import io.circe.syntax.*
import sttp.apispec.circe.*
import sttp.tapir.docs.apispec.schema.TapirSchemaToJsonSchema
import sttp.{apispec, tapir}
def decodeJson(jsonSchema: String): apispec.Schema =
io.circe.parser
.decode[apispec.Schema](jsonSchema)
.toTry
.get
def encodeJson(schema: apispec.Schema) = schema.asJson.deepDropNullValues.toString()
def apiSpecSchema[T: tapir.Schema] = TapirSchemaToJsonSchema(
implicitly[tapir.Schema[T]],
markOptionsAsNullable = true,
)
Then the following works correctly and assertion passes
implicit val GenderSchema = tapir.Schema.derivedEnumeration[Gender](encode = Some(_.toString))
val derivedSchema: apispec.Schema = apiSpecSchema[Gender]
val decodedSchema = decodeJson(encodeJson(derivedSchema))
assert(derivedSchema == decodedSchema)
But when using derivedEnumeration with the default encode function, the following code fails
implicit val GenderSchema = tapir.Schema.derivedEnumeration[Gender]()
val derivedSchema: apispec.Schema = apiSpecSchema[Gender]
val decodedSchema: apispec.Schema = decodeJson(encodeJson(derivedSchema))
assert(derivedSchema == decodedSchema)
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 TapirSchemaToJsonSchema and the derivedEnumeration handling shown in the reproduction. Run the two Scala examples and compare the apispec.Schema before and after the Circe JSON round trip, focusing on the default encode function. Done means the default enumeration encoding produces a schema that remains equal after encoding and decoding.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, scala
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100