scala-jsonschema
scala-jsonschema copied to clipboard
support generating schema from runtime classes
Let say I have TagType of Object and I want to generate schema for it.
@igreenfield if this is still relevant, could you please describe why do you need this? what's the problem of generating schemas at compile time?
I am using your lib to generate schema in the framework level so I don't have compile-time classes. in runtime I get the TagType of the class and I need a way to generate schema for that.
TagType - you mean TypeTag, right?
Let me clarify! You are saying that the model classes comes from some other jar. Right?
But those classes are still scala classes (case classes, sealed traits, etc). Right?
If so, you still can do
val myModelSchema = Json.schema[MyModelFromDependentJar]
- TagType - you mean TypeTag, right? Yes
- the class is known only on runtime. not compile time so I can't
This is interesting. How do you get typetag then?
If it is a true runtime usually you work at Class[_] level. Right?
You can create a typetag yourself out of class, but that is pretty tricky thing. So I am curious, how the things organized in your setup? Can you put some more detail on table?
I am using MethodMirror of methods I will run later and for each method parameter, I need to create a schema. Does that answer your question?
yes. ok, looks like i got it. you are developing a framework and you want end user to be able to receive json-schema generation functionality out of the box when using plain case classes for model definition. is that correct?
i will think about that. i didn't have intention to cover reflection-based models. but we'll see. until then can you tell me why you (as framework author) can't ask your end users to describe models in the way that framework would require? for example something like this would help
import json._
// framework api
trait ModelCompanion[T] {
implicit def schema: Schema[T]
}
// end user code
case class Foo(bar: String, baz: Int)
object Foo extends ModelCompanion[Foo] {
implicit def schema: Schema[Foo] = Json.schema[Foo]
}
// framework internals
def schemaFromClass(clazz: Class[_]): Schema[_] = {
import scala.reflect.runtime.{ universe => ru }
val mirror = ru.runtimeMirror(clazz.getClassLoader)
val module = mirror.staticModule(clazz.getName)
module.instance.asInstanceOf[ModelCompanion[_]].schema
}
i didn't try the code, but you've got the idea, right?
- Yes.
- for now that what I am doing the framework. all the idea of the framework is to remove the need of the user to configure it, so no mistakes.
you can generate this extra boilerplate yourself, right? i mean.. there are tools like
- macro-annotation
- compiler-plugin
or, in case you have time, contribution is appreciated.. i honestly don't know when i will have time for this problem
OK , I will see if I have time for that contribution.
I think i have a very similar use case: I would like to generate json schema for all classes within a package without writing code for each of it. At runtime it would be easy, just travers over all classes in the package using reflections or similar.
Is this somehow possible at compile time?
Yeah I have the same situation as @igreenfield -- I've got a trait which handles serialization over the network, and would like to augment it with schema generation functionality.
Using the package as is means going through hundreds of classes and adding a method override to generate the schema. That in turn means importing the package all over the place, lots of boilerplate, and degrading legibility of otherwise very small case classes.
It would be super nice to be able to just declare the schema value in my trait! Thank you @andyglow for the suggestions on macro-annotation and compiler-plugin, I plan to take a look at that, though my experience with those is limited.
hi @nightrise you guys probably already got it, got the fact that i personally strongly disagree with reflection based approach "the less reflection we use the better we sleep" - the slogan i would print on my t-short )
when i say disagree, i mean scala context. it's fine for java, that language is so restricted so reflection might seen a natural solution in that lands (oh, how many tears were shed because of this), but with scala you have much reacher platform to work directly with types
last couple of years my work requires me to use apache spark. besides the fact it it mostly written in scala, it uses reflection all over the place, and oh boy, how many inconsistencies we have because of that (randomly failed tests, jdk migration hell, etc) and how hard some time to debug that sort of issues
please think twice before getting into this reflection-based journey