tapir icon indicating copy to clipboard operation
tapir copied to clipboard

Auto-derive default values

Open jumale opened this issue 1 year ago • 1 comments

Maybe I'm missing something, but I could not find the way how to tell the schema derivation to automatically include the default values.

For example I have a case class:

import sttp.tapir._

case class Settings(isArchived: Boolean = false)
object Settings {
  implicit val schema: Schema[Settings] = Schema.derived
}

By default the property will be derived as required. But I want to make it optional based on the default value. For that I see 2 options:

  1. either modify the schema
object Settings {
  implicit val schema: Schema[Settings] = 
    Schema.derived
      .modify(_.isArchived)(_.default(false))
}
  1. or add an annotation:
case class Settings(@default(false) isArchived: Boolean = false)

In both cases it's a duplication, i.e. if I change later one and forget the other - then I have an inconsistent documentation.

Would it be possible to capture the default values during derivation? Something like Schema.derivedWithDefaultValues

Note: I use Play JSON for encoding, and it provides Json.using[WithDefaultValues].format[Settings] - that's why I assume that a property can be optional in a request if it has a default value.

jumale avatar May 29 '24 07:05 jumale

If I remember correctly we decided not to use the default values for (a) consistency with other schema configuration, (b) separating the schema that's exposed to users from the one that's used internally (you might not want to expose a default value to the outside world, but still use it internally).

Anyway, I think such customisation should be possible - probably Configuration would be the best place to put it? With some additional constructors to make the change binary-compatible.

adamw avatar Jun 17 '24 10:06 adamw