guardrail icon indicating copy to clipboard operation
guardrail copied to clipboard

akka routes not matching input with default property

Open dsilvasc opened this issue 5 years ago • 1 comments

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?

dsilvasc avatar Mar 19 '19 09:03 dsilvasc

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.

blast-hardcheese avatar Mar 19 '19 23:03 blast-hardcheese