Show HN: Jason – A new JSON Library for Go(github.com)
github.com
Show HN: Jason – A new JSON Library for Go
https://github.com/antonholmquist/jason
8 comments
(Another plug here) I did too! Except it runs in the browser: https://mholt.github.io/json-to-go
And I agree with you about the complementary aspect. Sometimes you can't control the fact that your JSON will have a widely varying structure... but when you can, these generators are nice.
And I agree with you about the complementary aspect. Sometimes you can't control the fact that your JSON will have a widely varying structure... but when you can, these generators are nice.
Seems very handy! Thank you
Great tool!
This.
If your main use case is JSON as a serialized representation of the ever same object (plus or minus a few optional fields), encoding/json is by far the fastest and most typesafe way to go.
(edit: Protip - for the really really fastest way to demarshal JSON, look here https://github.com/pquerna/ffjson for some reflection-free extra speed after your code has settled down)
But if your objects can be heterogenous for whatever reasons (think third-party systems, different languages, legacy stacks...) or you're dealing with different kinds of objects landing on the same controller, jason is the perfect complimentary device to deal with more dynamic structures. I've long sought for something like this, thanks to the OP!
If your main use case is JSON as a serialized representation of the ever same object (plus or minus a few optional fields), encoding/json is by far the fastest and most typesafe way to go.
(edit: Protip - for the really really fastest way to demarshal JSON, look here https://github.com/pquerna/ffjson for some reflection-free extra speed after your code has settled down)
But if your objects can be heterogenous for whatever reasons (think third-party systems, different languages, legacy stacks...) or you're dealing with different kinds of objects landing on the same controller, jason is the perfect complimentary device to deal with more dynamic structures. I've long sought for something like this, thanks to the OP!
I would say the most idiomatic way is having defined structs and using encoding/json. Even when you don't know the json schema in advance you can still parse it into an interface{}.
Here's an example: http://play.golang.org/p/jrqBcPuQei
Here's an example: http://play.golang.org/p/jrqBcPuQei
I use encoding/json for struct mapping when doing quick prototyping and simple applications.
Parsing gets much more interesting when you start supporting many clients, broad version ranges of protocols. At that point, a little flexibility starts to be a godsend. This is just my personal experience, but so far, in every language where I've tried direct struct mappers, they become less and less helpful as your product gains a real user base and you have to start doing compatibility "in the wild". You can certainly do it with encoding/json and custom marshallers, but this library seems like it might be helpful.
Protobufs have a lot of features that address this explicitly. I'm not a huge fan of protobufs (for a variety of off-topic reasons), but there's a great deal they got right: forcing consideration of backwards and forwards compatibility early is healthy for a project that's going to keep going for the long haul.
Parsing gets much more interesting when you start supporting many clients, broad version ranges of protocols. At that point, a little flexibility starts to be a godsend. This is just my personal experience, but so far, in every language where I've tried direct struct mappers, they become less and less helpful as your product gains a real user base and you have to start doing compatibility "in the wild". You can certainly do it with encoding/json and custom marshallers, but this library seems like it might be helpful.
Protobufs have a lot of features that address this explicitly. I'm not a huge fan of protobufs (for a variety of off-topic reasons), but there's a great deal they got right: forcing consideration of backwards and forwards compatibility early is healthy for a project that's going to keep going for the long haul.
You can parse JSON into an interface, but you end up doing tiresome casts if you structure is just somewhat nested.
...or use very simple lib like this one [1] to access to deep-nested structs using one call.
[1] https://github.com/zazab/zhash
[1] https://github.com/zazab/zhash
It's definitely safer, but it's a living hell having to define a class for each possible json structure in Java with gson.
Not sure where Java came into the conversation but I found a service[1] which I find really helpful for generating Golang structs from JSON. There is also a CLI tool[2] that does the same.
[1]http://mholt.github.io/json-to-go/
[2]https://github.com/ChimeraCoder/gojson
[1]http://mholt.github.io/json-to-go/
[2]https://github.com/ChimeraCoder/gojson
Another one.
https://github.com/str1ngs/jflect
https://github.com/str1ngs/jflect
For anyone wondering why this is necessary, as some others in this thread have mentioned, the standard go way to deserialize json is to pass a pointer to a struct, and the system will "fill" it with the json. There is no easy way to sort of "parse" json piece by piece, which is what this library provides
> There is no easy way to sort of "parse" json piece by piece
You mean like this? http://play.golang.org/p/mMh7HGuTbe
You mean like this? http://play.golang.org/p/mMh7HGuTbe
You're still parsing the entire JSON document at once. I believe what OP meant was getting a nested property without all the overhead of writing structs or parsing the entire JSON object into an interface{}, []string, map or whatever else is appropriate.
The jason package implementation decodes the entire JSON object to an interface{} using the standard encoding/json package.
> There is no easy way to sort of "parse" json piece by piece, which is what this library provides
Well, you can use json.RawMessage to delay decoding until other values are known[0].
However, this still requires that the input set is known at compile-time, which may not always be the case (some APIs sadly use a highly variable JSON schema, which can only be determined at runtime.)
You also don't need to pass a pointer to a struct. For example, you can pass an interface{}, which allows you to decode data into a type that is specified by the calling function, which I made heavy use of in this Twitter client library, for example[1].
(This is more or less how encoding/json itself works under the surface, when you think about it, but oftentimes people forget to take advantage of this idiom in practice.)
[0] http://golang.org/pkg/encoding/json/#RawMessage
[1] https://github.com/ChimeraCoder/anaconda/blob/master/users.g...
Well, you can use json.RawMessage to delay decoding until other values are known[0].
However, this still requires that the input set is known at compile-time, which may not always be the case (some APIs sadly use a highly variable JSON schema, which can only be determined at runtime.)
You also don't need to pass a pointer to a struct. For example, you can pass an interface{}, which allows you to decode data into a type that is specified by the calling function, which I made heavy use of in this Twitter client library, for example[1].
(This is more or less how encoding/json itself works under the surface, when you think about it, but oftentimes people forget to take advantage of this idiom in practice.)
[0] http://golang.org/pkg/encoding/json/#RawMessage
[1] https://github.com/ChimeraCoder/anaconda/blob/master/users.g...
>For anyone wondering why this is necessary, as some others in this thread have mentioned, the standard go way to deserialize json is to pass a pointer to a struct
I sometimes have trouble understanding Go. It kind of seems to retain a lot of the bad parts of C in terms of developer-friendliness, while still being relatively slower than C and garbage-collected.
I sometimes have trouble understanding Go. It kind of seems to retain a lot of the bad parts of C in terms of developer-friendliness, while still being relatively slower than C and garbage-collected.
What are you having trouble with in this instance? Pointers and structs? Both are very simple, well understood concepts. Their implementation in Go is also more syntactically clear than in C.
I understand pointers and structs just fine, it's just that you would think a modern language like Go would avoid use of pointers to structs and "bring-your-own-buffer" type calling conventions except wherever possible. It makes for ugly developer APIs, in my opinion.
That is, in a "friendly" language I expect to generate JSON like this (in pseudocode):
That is, in a "friendly" language I expect to generate JSON like this (in pseudocode):
HashMap parsed = JSON::parse("{1: 2}");
not JSONObj obj;
JSON::populate(&obj, "{1: 2}");The former is how it might work in a dynamically typed language. In a statically typed language, like Go, there are great benefits to decoding into the fields of struct with fields of known types.
IMHO there is something rigid in Go,like C rigid.Sure,there is no manual memory management.But a modern language shouldnt need explicit pointers.
> a modern language shouldnt need explicit pointers
I don't understand this. Can you clarify why you think this is a good idea?
My experience with languages that have implicit "references" (Python, Java, JavaScript) is that it's not clear when you're sharing and when you're copying data, leading to bugs and unnecessary allocations, respectively.
I don't understand this. Can you clarify why you think this is a good idea?
My experience with languages that have implicit "references" (Python, Java, JavaScript) is that it's not clear when you're sharing and when you're copying data, leading to bugs and unnecessary allocations, respectively.
[deleted]
Passing a pointer to a struct is just one way to use the standard Go package. You can also pass a pointer to an interface{}, []interface{} or map[string]interface{} depending on how much of the structure you know. You can also use these types in struct fields.
[deleted]
I've made something very similar for a current project and haven't gotten around to extracting it as a separate pkg yet, but it is much more loose on the coercion, e.g. when calling String() on an int(5) you will get back "5", etc.
Or to do a streaming parse with json.Decoder.
I would stray away from making the library name too similar in phonetic sound to the data it's meant to process. There was already enough confusion in an office I worked at with a non-developer whose name was "Jason"
Haha, okay. Yes, I just really like the name since it originates from an email sent from one of the project managers at our office: "Don't worry. We can handle both XML and Jason".
I would prefer something like Jason, even though it sounds like JSON, over something crazy like Unicorn Milk. I'm not saying you were suggesting something crazy, but just adding my two cents.
Come on, there's a huge middle ground between "Unicorn milk" and a name that isn't a homophone of the format it works with.
Let alone the fact that I don't like my first name being used as the name of a library, I think it's a bad choice as when you're verbally discussing this library with another person you'd likely have to refer to it as "jason the library" or something similar to clarify it rather than just using a simple unambiguous name.
I pronounce JSON as "jay-sawn" to avoid the confusion with the name. I've heard "jiss-on" and various other mutations used as well.
American? The North American accent pronounces "Python" similarly, as "py-THAWN" instead of "PIE-thn".
I usually pronounce it that way as well, I'm American, and it does rhyme with Python that way for me.
I pronounce it Jay-Ess-Owe-Enn, for obvious reasons.
How do you think this guy feels? http://en.wikipedia.org/wiki/Jake_Weary
Hint: Not the be confused with ...
Hint: Not the be confused with ...
Am I the only person who pronounces it as J-SON?
[deleted]
this looks quite familiar: https://github.com/likexian/simplejson-go
if anyone is interested i did some slight modifications to the project above which are keep in my personal fork: https://github.com/W4RH4WK/simplejson
if anyone is interested i did some slight modifications to the project above which are keep in my personal fork: https://github.com/W4RH4WK/simplejson
[deleted](4)
Shameless but relevant plug - if you do know the structure of your JSON in advance, I wrote a tool for automatically generating the appropriate struct definition for it: https://github.com/ChimeraCoder/gojson
(I see these as complimentary tools, rather than conflicting or competing, since they would have two different use cases).