andyglow / scala-jsonschema

Scala JSON Schema
Other
123 stars 38 forks source link

Getting schema from companion object will return companion object's first apply parameter #6

Closed SotaNakajima closed 5 years ago

SotaNakajima commented 5 years ago

If a case class has a companion object, it seems like we are unable to get the case class' parameters if there is an apply method with a parameter defined. The json schema will return a schema with the parameter's schema as the properties. See below.

  case class multiparam(p1: String, p2: Int, p3: Double)

  case class t1(foo: String, bar: String)
  object t1 {
    def apply(): t1 = t1("","")
    def apply(foobar: multiparam): t1 = t1("foo","bar")
    def apply(int: Int): t1 = t1("1","2")
  }

  case class t2(foo: String, bar: String)
  object t2 {
    def apply(): t2 = t2("","")
    def apply(int: Int): t2 = t2("1","2")
    def apply(foobar: multiparam): t2 = t2("foo","bar")
  }

  case class t3(foo: String, bar: String)
  object t3 {
    def apply(): t3 = t3("","")
  }

  def main(args: Array[String]): Unit = {
    def pprint(obj: json.Schema[_]) = { println(s"\n\n=====================\n${JsonFormatter.format(AsValue.schema(obj))}")}

    pprint(Json.schema[t1])
    pprint(Json.schema[t2])
    pprint(Json.schema[t3])
  }

yields

=====================
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "foobar": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "p1": {
          "type": "string"
        },
        "p2": {
          "type": "integer"
        },
        "p3": {
          "type": "number"
        }
      },
      "required": [
        "p1",
        "p2",
        "p3"
      ]
    }
  },
  "required": [
    "foobar"
  ]
}

=====================
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "int": {
      "type": "integer"
    }
  },
  "required": [
    "int"
  ]
}

=====================
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "string"
    }
  },
  "required": [
    "foo",
    "bar"
  ]
}

Is there any way to get the schema of the parameters of the case class (like t3) if there is an apply function with parameters already?

andyglow commented 5 years ago

Parameter are being taken from constructor. Macros doesn't make difference for where it comes from. From case class definition or from companion object. Simplest solution i can propose, not sure if is fits with your vision, is to not overload constructors. BTW: what library do you use for json deserialization and how do you handle the same problem there?

SotaNakajima commented 5 years ago

Oh I see. Unfortunately this is not a viable solution for me. This would be my first time dabbling in json related tasks so I have not run into this issue before. Sorry I can't help. Thanks for the clarification!