Add support for json schema draft 4, 6 and 7

95 views
Skip to first unread message

rajnish

unread,
Oct 21, 2020, 12:31:44 PM10/21/20
to jackson-dev
I raised the issue for this https://github.com/FasterXML/jackson-module-jsonSchema/issues/141

  Given that this change has not been picked up yet, I am trying to see if any one wants to join hands on this change. I am planning to start work on this. If anyone has made attempt in this regard, please let me know.

   Following is summary of my evaluation so far.

Breaking changes between 3 and upward are minimal. For example, required field got changed from boolean to array at object type. Locally, when I removed the required attribute from JsonSchema and put at ObjectSchema level, parsing happened correctly.
  Given that Json specs has tendency to break the compatibility, I recommend to have types per schema version even if it means code duplication similar to apache commons approach. This will ensure that each version implementation  stay independent and not causing regression in older implementation.

  mbknor seems to have spent lot of time analyzing and trying to reuse existing but finally gave up and wrote a totally different implementation

Based on his experience, I am recommending cloning the  spec 3 implementation, copy for new version and try not reusing types between the version. We can refactor to use classes that has lot of logic so that those stays common across different version.  

Please let me know if any one has other thoughts on how to add support for new version.  I am open to any idea that can make supporting new spec version seamless.

-Rajnish










Tatu Saloranta

unread,
Oct 21, 2020, 2:43:56 PM10/21/20
to jacks...@googlegroups.com
Sounds reasonable wrt not trying to maximize code reuse. It is
possible create a shared "common" package, if there is absolute need
-- or not -- there are examples of both:

* Hibernate datatype has 3 implementations, no shared code
* JAX-RS has multiple datatype backends, all of which share "base"
package (separate jar)

One other question I have is just about your usage; how do you use
this package? (just curious about common usage)

-+ Tatu +-

>
> -Rajnish
>
>
>
>
>
>
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "jackson-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jackson-dev...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-dev/3f64c7cd-d10b-4c50-91d6-fbdb252456d3n%40googlegroups.com.

rajnish

unread,
Oct 21, 2020, 5:35:40 PM10/21/20
to jackson-dev
Thanks Tatu. I will look into the examples that you mentioned and see how we can organize the different version support nicely in parameterized way. 

I have two use cases. 
1) Create Json schema with  latest version (preferably, I want to be able to take schema version as parameter in my api)
2)Given the Jason schema, convert it into internal proprietary schema. So far, among all the java library I evaluated , no one expose the api to get attributes out of Json schema rather all are focussed solely on  doing validation. When I looked in this library, what it appeals to me that I can get a object of type JsonSchema from which I can get all the Json schema attributes. Here is how I am using this. 
  
val objectMapper = jacksonObjectMapper()

objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

val jsonSchema: MySchema = objectMapper.readValue(json)

@JsonTypeIdResolver(MyResolver::class)
class MySchema : ObjectSchema()

internal class MyResolver : JsonSchemaIdResolver() {
override fun idFromValue(value: Any): String {
return if (value is MySchema) {
"object"
} else super.idFromValue(value)
}

override fun idFromValueAndType(value: Any, suggestedType: Class<*>?): String {
return if (value is MySchema) {
"object"
} else super.idFromValueAndType(value, suggestedType)
}

override fun typeFromId(
ctxt: DatabindContext,
id: String
): JavaType {
return if ("object" == id) {
ctxt.constructType(MySchema::class.java)
} else super.typeFromId(ctxt, id)
}
}

Tatu Saloranta

unread,
Oct 25, 2020, 12:10:37 PM10/25/20
to jacks...@googlegroups.com
On Wed, Oct 21, 2020 at 2:35 PM rajnish <raj...@gmail.com> wrote:
>
> Thanks Tatu. I will look into the examples that you mentioned and see how we can organize the different version support nicely in parameterized way.

Ok. Also, one thing I would suggest is to consider which schema
versions are widely used, in case some intermediate versions might be
obsolete.
Might make sense to skip some (I assume v5 falls into this category).

> I have two use cases.
> 1) Create Json schema with latest version (preferably, I want to be able to take schema version as parameter in my api)
> 2)Given the Jason schema, convert it into internal proprietary schema. So far, among all the java library I evaluated , no one expose the api to get attributes out of Json schema rather all are focussed solely on doing validation. When I looked in this library, what it appeals to me that I can get a object of type JsonSchema from which I can get all the Json schema attributes. Here is how I am using this.

Interesting. I agree that programmatic access to Schema object is valuable.
Seems odd other packages do not expose that.

>
> val objectMapper = jacksonObjectMapper()
>
> objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)
>
> objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
>
> val jsonSchema: MySchema = objectMapper.readValue(json)
>
> @JsonTypeIdResolver(MyResolver::class)
> class MySchema : ObjectSchema()
>
> internal class MyResolver : JsonSchemaIdResolver() {
> override fun idFromValue(value: Any): String {
> return if (value is MySchema) {
> "object"
> } else super.idFromValue(value)
> }
>
> override fun idFromValueAndType(value: Any, suggestedType: Class<*>?): String {
> return if (value is MySchema) {
> "object"
> } else super.idFromValueAndType(value, suggestedType)
> }
>
> override fun typeFromId(
> ctxt: DatabindContext,
> id: String
> ): JavaType {
> return if ("object" == id) {
> ctxt.constructType(MySchema::class.java)
> } else super.typeFromId(ctxt, id)
> }
> }

-+ Tatu +-
> To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-dev/fbf29cb7-5416-4b47-a404-ba7069e9daebn%40googlegroups.com.

rajnish prasad

unread,
Oct 26, 2020, 1:39:06 PM10/26/20
to jacks...@googlegroups.com
That's correct version 5 does not need to be supported.

-Rajnish

Reply all
Reply to author
Forward
0 new messages