softwaremill / tapir

Rapid development of self-documenting APIs
https://tapir.softwaremill.com
Apache License 2.0
1.33k stars 404 forks source link

Auto-derive default values #3800

Open jumale opened 1 month ago

jumale commented 1 month ago

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))
    }
  2. 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.

adamw commented 1 month ago

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.