-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support custom Json deserializer/serializer #6
Comments
Hi @volyx. Thanks for submitting this request. The use of Jackson in the library is mostly private, meaning that Jackson classes aren't returned from the methods. Is your need for GSON so that you don't need to include Jackson in your classpath? |
Yes, I already exclude all jackson libraries from my project for using only Gson, but I can't replace Jackson with Gson in fusionauth-jwt. So it would be nice to have a opportunity to somehow register custom serializer/deserializer. For example
|
Thanks for that additional info @volyx . In theory we could abstract the mapper interface and allow a different module / library to be bound for serializing and deserializing. Most of that code is in We are using the Jackson While not ideal, you could fork the repo and just rip out Jackson. I'm open to this feature in FusionAuth JWT - we'd need to move the Jackson annotations out of the domain and into some other configuration, or perhaps we could use Jackson mixins to decorate the domain with the annotations we'd need. If that was all done, then it wouldn't be too hard to make a new interface for Guice to bind one of several implementations. This isn't a high priority - but we can leave this open and see if we have some time to hack on it a bit. Feel free to offer some example code or PRs if you have an idea of how it would work. Thanks! |
outdatedAs I see there are two options:
So users can still use
So user could exclude Jackson, and add Gson library. First approach more modular, and allow future extension but needs more work and restructurization. |
PoC for removing JacksonProblem: Jackson libraries are performant but heavy weight and clash with other Jackson libraries in a project Solution: use lightweight JSON library or do not even use any JSON library - decode/encode manually Library sizes: 340K jackson-core-2.10.1.jar fusionauth-jwt library is just 136 Kilobytes. For comparison I have added JSON serializers, deserializers which can replace Jackson. I have tested three options: minimal-json, nanojson(embeded), plain(manual) All them can be tested for compatibility with Jackson ObjectMapper like this: The same is for others encoders/decoders: I wrote benchmark for testing the performance of all these JSON mappers -
Jackson and Plain mappers are comparable by average speed and throughput. So, can we maybe completely replace Jackson with own custom JsonReader/PlainObjectMapper implementation? WDYT? @robotdan Code is here - https://github.com/volyx/fusionauth-jwt/tree/minimal-json PlainObjectMapper - https://github.com/volyx/fusionauth-jwt/blob/minimal-json/src/main/java/io/fusionauth/jwt/json/PlainObjectMapper.java NanoJsonObjectMapper - https://github.com/volyx/fusionauth-jwt/blob/minimal-json/src/main/java/io/fusionauth/jwt/json/NanoJsonObjectMapper.java MinimalJsonObjectMapper - https://github.com/volyx/fusionauth-jwt/blob/minimal-json/src/main/java/io/fusionauth/jwt/json/MinimalJsonObjectMapper.java |
Wow, thanks for the excellent and thorough suggestion @volyx I'll take a look at you're proposal and follow up with comments. |
Can this be pluggable (i.e. done via an interface)? While I do understand that not all projects use Jackson, it's de facto standard for anyone using Spring Boot (and possibly other popular web frameworks). Meaning that it wouldn't really add any extra dependencies. Pluggability may also help with writing simpler tests (possibly allow to test the validation and JSON parsing logic separately) and allow further Jackson mapper customization via the usual module/mixin/options route. This will not be as easy as throwing away Jackson completely (you may have to do Mixins for serialization/deserialization to keep using Jackson annotations and do default ObjectMapper configuration), but avoids depending on yet-another-custom-json-parser that's only used here. |
Example is here - PlainObjectMapper. It is as fast as Jackson and uses just standard Java APIs. I don't see any reason to support custom JSON serialization, if I can do encode/decode internally without any dependencies.
|
The same approach of embedding JSON serialization/deserialization code inside library is used in jose4j - https://bitbucket.org/b_c/jose4j/src/master/src/main/java/org/jose4j/json/ |
First of all I don't think speed is the main reason anyone uses Jackson (or Spring for that matter). Jackson and Gson provide a wide range of serialization/deserialization customization options, are well established, with decent documentation and have plenty integrations with other libraries. As a developer I don't want to write glue logic just to interface with the embedded serializer of a yet-another-jwt-library with my Jackson object model when I have the option of not doing so if I use a library that natively supports Jackson, even if it's a little slower/bulkier/... I'd like to emphasize that I'm not against having a custom-very-fast-json-library even as the default option, but please don't make it hard not using it. |
@virtual-machinist I'm fully agree with you point. But what if you don't even need to think about the internal serialization/deserialization logic? Speed benchmarks are presented there only to show that the performance will not get worth after the replacement. |
Sorry, @volyx , I cannot imagine a case when I'd like to add a private claim of my own object model to the token and not think about the serialization details. You're basically saying I won't have to worry about I/O because I won't have the option. 😉 I think this discussion is getting nowhere. I am for an agnostic model with first-class parser/generator access to JSON claims and header and I'm against hand-rolled JSON processing with the necessity of writing glue logic from my claims model. Especially if there's no obvious overhead of having Jackson, cause it's together with Spring. If the model is truly agnostic, there's no problem writing a @robotdan , I'm sorry if this has already been asked - why public fields and not getters/setters? |
For example Gson instead Jackson.
Move json to another maven module and allow to add it as separate jar.
The text was updated successfully, but these errors were encountered: