guardrail
guardrail copied to clipboard
Support for Any Type property in schema
Open Api Specification mentioning Any Type
based on that i tried to define
EntityWithProp:
type: object
properties:
id:
type: string
name:
type: string
prop:
anyOf:
- type: string
- type: number
- type: integer
- type: boolean
- type: array
items: { }
- type: object
description: 'Can be anything: string, number, array, object, etc.'
x-scala-type: io.circe.Json
required:
- id
- name
- prop
but code generator will produce
case class EntityWithProp(id: String, name: String, prop: EntityWithProp.Prop)
object EntityWithProp {
implicit val encodeEntityWithProp: Encoder.AsObject[EntityWithProp] = {
val readOnlyKeys = Set[String]()
Encoder.AsObject.instance[EntityWithProp](a => JsonObject.fromIterable(Vector(("id", a.id.asJson), ("name", a.name.asJson), ("prop", a.prop.asJson)))).mapJsonObject(_.filterKeys(key => !(readOnlyKeys contains key)))
}
implicit val decodeEntityWithProp: Decoder[EntityWithProp] = new Decoder[EntityWithProp] { final def apply(c: HCursor): Decoder.Result[EntityWithProp] = for (v0 <- c.downField("id").as[String]; v1 <- c.downField("name").as[String]; v2 <- c.downField("prop").as[EntityWithProp.Prop]) yield EntityWithProp(v0, v1, v2) }
}
where EntityWithProp.Prop is missing (probably this is because anyOf is not supported in this generator)
in compare schema with dictionary
EntityWithProps:
type: object
properties:
id:
type: string
name:
type: string
props:
type: object
additionalProperties: true # anyval for value
required:
- id
- name
- props
is generated without issues
case class EntityWithProps(id: String, name: String, props: Map[String, io.circe.Json] = Map.empty)
object EntityWithProps {
implicit val encodeEntityWithProps: Encoder.AsObject[EntityWithProps] = {
val readOnlyKeys = Set[String]()
Encoder.AsObject.instance[EntityWithProps](a => JsonObject.fromIterable(Vector(("id", a.id.asJson), ("name", a.name.asJson), ("props", a.props.asJson)))).mapJsonObject(_.filterKeys(key => !(readOnlyKeys contains key)))
}
implicit val decodeEntityWithProps: Decoder[EntityWithProps] = new Decoder[EntityWithProps] { final def apply(c: HCursor): Decoder.Result[EntityWithProps] = for (v0 <- c.downField("id").as[String]; v1 <- c.downField("name").as[String]; v2 <- c.downField("props").as[Map[String, io.circe.Json]]) yield EntityWithProps(v0, v1, v2) }
}
in case of EntityWithProp, i think it should be similar, and generated code should be like
case class EntityWithProp(id: String, name: String, prop: io.circe.Json)
what do you think about that?
thank you for your response
Peter