guardrail
guardrail copied to clipboard
akka routes not matching input with default property
I have an API where the Create operation consumes a resource without an ID field (the server generates it) and where every operation returns that same resource with an ID field.
definitions:
TheResource:
discriminator: type
type: "object"
required:
- "type"
properties:
id:
type: "string"
type:
type: "string"
...
Guardrail generates an id
field of type Option[String]
. If I change the id
property in swagger to have a default: ""
and/or add id
to the list of required properties, Guardrail changes the case class accordingly (either as id: Option[String] = Option("")
or id: String = ""
), but the generated routes don't match requests without an ID.
I think this should be possible in swagger 2 and 3. Is there an extra hint I should be providing to the akka server routes generator?
Hey @dsilvasc, thanks for the report! I expect this is due to the generated decoders not explicitly handling default values.
This is similar to #94, with the unfortunate workaround being (as you may already suspect) manually handling these use cases for now.
I think the fix for this is much more straightforward than read/write-only properties, as we can always fall back to a default value.
Taking a similar strategy to x-scala-empty-is-null
seems like a good direction for a fix:
implicit val decodePet = new Decoder[Pet] {
final def apply(c: HCursor): Decoder.Result[Pet] =
for (
name <- c.downField("name").withFocus(j => j.asString.fold(j)(s => if (s.isEmpty) Json.Null else j)).as[Option[CustomThing]]
) yield Pet(name)
}
could easily be modified with j.asString.orElse(...)
without negatively impacting other functionality.