Original SLIP Thread: https://github.com/scala/slip/pull/28
Gitter Channel: https://gitter.im/mdedetrich/scala-json-ast
This proposal is about adding a standard Scala Json AST module to the SP. The goal of the scala-json-ast is as follows. The current implementation can be viewed at https://github.com/mdedetrich/scala-json-ast (easily read version can be read here https://github.com/mdedetrich/slip/blob/274307b68a13aa242ead7ee7fdb0d2fd3e6bc45f/text/json-ast.md)
Current State of Ecosystem
Currently Scala is an unfortunate position where it has roughly 6 competing JSON AST, these JSON AST’s usually differ in subtle ways. Due to not having an establised way to represent a JSON AST, libraries that need to work with JSON often have to write wrappers for every single JSON library out there. This becomes very problematic considering that each of these JSON libraries have their own lifecycles and often have their own dependencies/obligations. The effects of this can be seen in libraries like slick-pg https://github.com/tminglei/slick-pg
The lack of a standard JSON AST is creating problems similar to what exists in Haskell ecosystem in regards to String (i.e. multiple competing String types which libraries/frameworks have to deal with). The idea is to introduce 2 JSON types, scala.json.ast.JValue and scala.json.ast.unsafe.JValue which can be passed around by various frameworks and libraries.
Goals
- Strictly only AST’s. This proposal does not propose a JSON parser, nor guidelines on how to handle errors. This is up to both web frameworks and JSON parsers as they see fit.
- Provides 2 AST’s
- One is for idiomatic Scala use. Contains immutable data structures with predictable performance (including key lookup for JSON objects and index lookup for Json Arrays). Also uses the recommended data structures according to the JSON standard https://tools.ietf.org/html/rfc7159, i.e. JSON objects is an unordered Map with unique values per key. Also mandates validation so its guaranteed to contain a valid JSON value if the value exists
- One for atypical Scala use (called unsafe). Contains high performance data structures (mutable and immutable) as well as the ability to handle specific cases (i.e. ordering for Maps as well as supporting multiple values per key in cases of serialization).
- Ability to seamlessly convert from standard to unsafe and vice versa
- Scala 2.10, 2.11 and 2.12 support as well as Scala.js support.
- For Scala.js, uses the appropriate underlying Javascript data structures for the unsafe AST to maintain performance (i.e. uses js.Array instead of Scala Array)
- Designed to be ultra stable and to never change unless critical issues are found
- Strictly zero dependencies
- Already part of the scala platform continuous integration as well as the sbt-platform-plugin
- Comprehensive test suite for all platforms, including benchmarks
History and community adoption
The original idea to create a common JSON dates back years when Json4s, Play and Spray attempted to collaborate to create a standard JSON AST that they could share. Unfortunately the person pushing for the common AST no longer does Scala work, and since then the proposal has laid dormant until it was revived. Initially the revival was to make the JSON AST to be part of the Json4s project however since the introduction of SLIP’s it was decided that making the JSON AST to be part of the Scala Library (and now the Scala Platform as a module) was better idea for achieving its goals.
Numerous libraries and framework authors have signalled their interests for adopting the JSON AST in its current form, this includes
- All lightbend/typesafe libraries+ framworks, i.e. Play, Akka-Http, Lagom, Akka see https://github.com/scala/slip/pull/28#issuecomment-263517532 for most recent confirmation
- SBT 1.0 uses the JSON library as part of their communication. See https://gitter.im/scala/slip?at=583eca7d73abd79c55b5db53 and http://eed3si9n.com/sjson-new-and-the-prisoner-of-azkaban
- Lift https://gitter.im/mdedetrich/scala-json-ast?at=56d9b37968ddef776468a0bf
- Jawn - will add scala-json-ast to one of their supported libraries. Still a question whether Jawn will use the unsafe AST internally for parsing
- Circe - Considering adding interopt for the Scala Json AST
- Play Json pull request which uses Scala Json AST rather than play-json https://github.com/mdedetrich/playframework. Demonstrates integration in release frameworks/libraries
Note that these are the most recent references, you can see more older ones at the SLIP here https://github.com/mdedetrich/slip/blob/274307b68a13aa242ead7ee7fdb0d2fd3e6bc45f/text/json-ast.md#references---quotes-from-gitter
The development of the Sclaa Json AST was also done with collaboration within the Scala community for over a year and as far as I know, most major concerns with the actual design of the Scala JSON AST were (at worst) adequately resolved.