Which API for a future, modern JSON library?

464 views
Skip to first unread message

Thomas Broyer

unread,
Dec 11, 2017, 7:25:04 AM12/11/17
to GWT Contributors
Hi all,

Following up on https://github.com/gwtproject/gwt/issues/9484#issuecomment-277216304, I've been toying around to build a new JSON library for GWT.
Note that my goal is to have a lightweight library that could be used both on the client-side with GWT (and then j2cl), and on the server-side or in any JVM; and "mapping" to/from POJOs is (currently) out of scope.

What do you think would be the best API?

  • Same as com.google.gwt.json.
    This API is IMO verbose, and is based on wrapper objects that add runtime overhead.
  • Same as elemental.json, except for JsonNull which goes away (represented by a Java 'null' and interchangeable with 'undefined').
    Lighter-weight, both in terms of API verbosity and runtime overhead (no wrapper object).
    Based on type coercion (you can ask every JsonValue to be returned as a boolean, double, or String, and value will be coerced accordingly).
    elemental.json "JRE" types are also usable on client-side, and can be transported through GWT-RPC; I believe this is an aspect that we cannot preserve.
  • Similar to jsinterop-base's Any, JsPropertyMap and JsArrayLike (for JsonValue, JsonObject and JsonArray respectively), and using Java String and primitives for other value types; and probably with the addition of a JsonType enum (or isXxx methods) on Any/JsonValue to be able to tell value types apart before you call the (throwing) asXxx methods.
    This is actually similar to elemental.json but without the JsonBoolean, JsonNumber, and JsonString types; and it throws rather than coercing values.
    This could even go farther and directly use JsonValue[] instead of JsonArray.
  • Something else?
One question also is whether this should be used for consuming JSON mostly, or also for creating JSON (you'd generally use POJOs and serialize them to JSON I believe, but there may be cases where you want to create a dynamic structure that you cannot easily represent as a tree of POJOs), and/or "updating/modifying JSON" (parse, update, stringify).

Fwiw, this would also be a good opportunity to shape how a cross-platform library would be developed in terms of project layout and tooling (in both Gradle and Maven).

Wrt the JVM/server-side support, what JSON parsing library should be used? I was heading towards the lightweight Moshi from Square, but I believe there could possibly be several "adapters" for Moshi, GSON, Jackson, etc. (and even org.json's JsonTokenizer/JsonStringer)

Colin Alworth

unread,
Dec 11, 2017, 10:01:41 AM12/11/17
to GWT Contributors
Thanks Thomas, I'm excited to see where this will lead.

Can you talk a little more about plans POJO support, as none of the three existing options have any? Would you envision a wrapping tool that looks like AutoBean/gwt-jackson, and where on that continuum are you thinking (autobean is as late as possible, and generic enough to handle xml or other underlying data formats, gwt-jackson parses then copies all json tree nodes directly to bean values)? I also know there have been some experiments around passing a reviver func to JSON.parse that could be interesting here. Any thoughts on handling collections, whether to go with java.util, or try for something shared js/jvm and only used within this library?

As a replacement for elemental.json or c.g.g.json, I would personally imagine only the json node tree support. I'm aware that work is ongoing already to update gwt-jackson to move to APT, and am considering trying AutoBeans myself, mostly because i find it so handy when I want to write strongly typed java around plain json.

My only thought on adapter vs starting with a specific jre parser is that there is a lot of flexibility/depth already in this project - perhaps just keep the internals as private as possible, and leave room for such adapters in vers 2?

Thomas Broyer

unread,
Dec 11, 2017, 11:13:40 AM12/11/17
to GWT Contributors


On Monday, December 11, 2017 at 4:01:41 PM UTC+1, Colin Alworth wrote:
Thanks Thomas, I'm excited to see where this will lead.

Can you talk a little more about plans POJO support, as none of the three existing options have any? Would you envision a wrapping tool that looks like AutoBean/gwt-jackson, and where on that continuum are you thinking (autobean is as late as possible, and generic enough to handle xml or other underlying data formats, gwt-jackson parses then copies all json tree nodes directly to bean values)? I also know there have been some experiments around passing a reviver func to JSON.parse that could be interesting here. Any thoughts on handling collections, whether to go with java.util, or try for something shared js/jvm and only used within this library?

No plan. at all. really.
Might even never be in scope.

What would look the closest to a plan would be to somehow expose the "raw" objects so you could "cast" them to jsinterop native types (collections are an issue there). And by using an API like "<T> T cast(Class<T> clazz)", a JVM adapter could use its own logic to do the mapping into new objects (note that JS and JVM would have different behavior wrt updating the objects) Raw objects could possibly also be fed into "wrappers" like AutoBeans (btw, if it weren't for the –understandable– JsInterop limitation that a native type cannot implement/extend a non-jstype interface, AutoBeans would probably not have to be wrappers, but only native or overlay methods and WeakMap for reified types; if the "schema" wasn't the Java interface you actually use in your code, those could easily be generated).

jay

unread,
Dec 11, 2017, 2:11:57 PM12/11/17
to GWT Contributors
Out of curiosity, why not use the org.json API?

jay

Peter Donald

unread,
Dec 11, 2017, 3:39:52 PM12/11/17
to google-web-tool...@googlegroups.com
Hi,

Have you considered the javax.json API? There are some parts that may
not be able to be directly translated but from memory it should mostly
work. The "advantage" is that it is a standard that is starting to
gain traction and will likely be present in lots more APIs as more of
the EE stack adopts it. The "disadvantage" is that the api is a bit
more primitive and it evolves slowly. It could probably be done with
just @JsOverlay methods and a few adapter classes. Another
disadvantage is that it is an immutable/read-only API.

As for json writing - We tend to use @JsType annotated classes and
have yet to come up with a use case where we would need to drop down
to JsPropertyMap.

--
Cheers,

Peter Donald

Slava Pankov

unread,
Dec 11, 2017, 4:44:07 PM12/11/17
to GWT Contributors
I think it's better to replicate GSON like API on client side. Another option is doing better version of RestyGWT without GWT.create()

Thomas Broyer

unread,
Dec 16, 2017, 11:03:39 AM12/16/17
to GWT Contributors


On Monday, December 11, 2017 at 9:39:52 PM UTC+1, Peter Donald wrote:
Hi,

Have you considered the javax.json API?

No, just like I didn't consider org.json.
 
There are some parts that may
not be able to be directly translated but from memory it should mostly
work. The "advantage" is that it is a standard that is starting to
gain traction and will likely be present in lots more APIs as more of
the EE stack adopts it. The "disadvantage" is that the api is a bit
more primitive and it evolves slowly. It could probably be done with
just @JsOverlay methods and a few adapter classes.

I think it would mostly involve adapter classes (JsonObject extends Map, JsonArray extends List; so they cannot be implemented as native types)
 
Another
disadvantage is that it is an immutable/read-only API.

It's actually not: JsonObjectBuilder and JsonArrayBuilder allow constructing values.

Thomas Broyer

unread,
Dec 16, 2017, 11:24:19 AM12/16/17
to GWT Contributors


On Monday, December 11, 2017 at 10:44:07 PM UTC+1, Slava Pankov wrote:
I think it's better to replicate GSON like API on client side. Another option is doing better version of RestyGWT without GWT.create()

Do you mean GSON's JsonElement API, or mapping to POJOs?
If the latter, then it's out of scope.
(I'm not saying it's not an interesting goal, it's just not the one I'm pursuing here)

Goktug Gokdogan

unread,
Dec 16, 2017, 11:55:29 PM12/16/17
to google-web-toolkit-contributors
Inline with what others asked; I think it is best to start with emulating an existing established API instead of introducing a new proprietary API - assuming they could be emulated with a reasonable performance.


--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/12c77fe4-0509-46e3-b1d3-bdcdbe8040fb%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Alexander Bertram

unread,
Dec 17, 2017, 5:17:20 PM12/17/17
to GWT Contributors
The problem with most existing APIs is that they tend to use polymorphism, and expressions like "value instanceof JsonArray". This makes it hard to map to a plain Javascript object.

After much frustration, we have recently rolled our own json library, that combines the old JSON elemental library, our Gson-gwt library (https://github.com/akbertram/gson-gwt) and @JsTypes.

We introduce a single interface, JsonValue, which has a server-side implementation based on I think Json.org, and client-side implementation that maps directly to plain JavaScript objects:

This means that you can cast a JsonValue directly to a type annotated with 

@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")

on the client side via simple assignment and on the server side using reflection, with a common API (Json.fromJson)

It's very poorly documented and still has a lot of left over cruft from the original sources, but it's working well and we'll continue to develop it.

Sources are here:

If any one is interested in working on it, we'll spin out to a seperate repo with an Apache license.

Best,
Alex

Ahmad Bawaneh

unread,
Dec 27, 2017, 9:56:56 AM12/27/17
to GWT Contributors
Hi
I have been working on an adaptation of gwt-jackson that uses APT instead of generators

https://github.com/vegegoku/gwt-jackson-apt

now i have plans to support using the same API for both client side and server side and want to consider the JsXxxx types as supported types for Serialization/Deserialization.

If anyone is interested i welcome any type of  feedback

Ahmad Bawaneh

unread,
Jan 11, 2018, 4:48:34 AM1/11/18
to GWT Contributors

I am glad to announce the latest jackson-apt that provide support for using the same mapper instance on both client side and server side, finally you can annotate the type in the shared module and generate a mapper into the shared module and use it in both client code and server code, sample have been included in the repository and a snapshot is now avialble, please read the README. file for the new dependencies. :smile:


also you can join me in the gwt-jackson-apt channel for discussions, feedback, questions, opinions.. and what ever you think is interesting.. :smiley:


On Monday, December 11, 2017 at 2:25:04 PM UTC+2, Thomas Broyer wrote:
Reply all
Reply to author
Forward
0 new messages