guardrail-dev / guardrail-dev/guardrail

Support for Any Type property in schema

Open
#1,152 0 comments 0 reactions 0 assignees View on GitHub
enhancement help wanted
Dominant language
Scala
Stars
541
Forks
138
PR merge metrics
No merged PRs in 30d

Description

[Open Api Specification](https://swagger.io/docs/specification/data-models/data-types/) mentioning Any Type

based on that i tried to define

``` yaml
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

```scala
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

```yaml
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

```scala
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

```scala
case class EntityWithProp(id: String, name: String, prop: io.circe.Json)
```

what do you think about that?

thank you for your response

Peter

Contributor guide

Open the contributing guide

Research direction

The issue names no source file or test; start by tracing how the generator handles the shown anyOf schema and compare it with the working additionalProperties case. Done means the EntityWithProp example generates prop as io.circe.Json with corresponding encoding and decoding.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, scala
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.