What is the difference between JSON 'encoding/decoding' and JSON 'marshalling/unmarshalling'?
Trying to learn how to write a RESTFUL api in golang and not sure what the difference between JSON 'encoding' and 'marshalling' is or if they are the same?
Marshal => String
Encode => Stream
Marshal and Unmarshal convert a string into JSON and vice versa. Encoding and decoding convert a stream into JSON and vice versa.
The below code show working of marshal and unmarshal
type Person struct {
First string
Last string
}
func main() {
/* This will marshal the JSON into []bytes */
p1 := Person{"alice", "bob"}
bs, _ := json.Marshal(p1)
fmt.Println(string(bs))
/* This will unmarshal the JSON from []bytes */
var p2 Person
bs = []byte(`{"First":"alice","Last":"bob"}`)
json.Unmarshal(bs, &p2)
fmt.Println(p2)
}
Encoder and decoder write struct to slice of a stream or read data from a slice of a stream and convert it into a struct. Internally, it also implements the marshal method. The only difference is if you want to play with string or bytes use marshal, and if any data you want to read or write to some writer interface, use encodes and decode.
Generally, encoding/decoding JSON
refers to the process of actually reading/writing the character data to a string or binary form. Marshaling/Unmarshaling refers to the process of mapping JSON
types from and to Go
data types and primitives.
Actual encoding can include things like serializing unicode characters for example. I think they may be used somewhat interchangeably in documentation sometimes because they generally occur in the same step. The Marshal function for example, will determine which JSON type to marshal something to, and then it will be encoded in string form (which may include other details such as special characters if its textual data).
You can consult the go json package docs for more details on how the marshaling/unmarshaling steps work.
What is the difference between JSON 'encoding/decoding' and JSON 'marshalling/unmarshalling'?
Marshaling and Encoding are of course different concepts, better addressed on Wikipedia (or elsewhere). But in short, objects are marshaled into JSON encoded strings.
Also don't let the Golang json.NewEncoder
/ (json.Encoder).Encode
and json.Marshal
methods confuse you. They both marshal objects into JSON encoded strings. The difference being the Encoder, first marshals the object to a JSON encoded string, then writes that data to a buffer stream (or Data Buffer on Wikipedia). The Encoder therefore, uses more code and memory overhead than the simpler json.Marshal
.
You can also see this in the Golang source code:
Marshal: https://golang.org/src/encoding/json/encode.go?s=6458:6501#L148
Encode: https://golang.org/src/encoding/json/stream.go?s=5070:5117#L191
Typically, if you need to send the JSON encoded string to a file system, or as an HTTP response, you may need the use of a buffer stream. However, you can also send this JSON encoded string without a buffer stream using a pipe.
func Encode is a method on an Encoder, which writes JSON encoded Go types to an output stream (func NewEncoder takes an io.Writer and returns a *Encoder).
Your Go types enter the black box and are written out to the stream in JSON formatting.
Marshal is a function that returns JSON encoding of Go types.
Here your Go types enter the black box and come out of the box in JSON formatting.
It's well documented at: golang.org/pkg/encoding/json/
There is not a lot of difference between these methods, it's more depends on your usage, If you have io.Reader (for example: when you are working with HTTP or file system), it's easier to use NewDecoder:
https://i.stack.imgur.com/QcOyh.png
It gives io.Reader and returns *Decoder type, then you chain a Decode method to it:
https://i.stack.imgur.com/kYFcG.png
And this Decode method will write data to v that you passed to it as a parameter.
On the other hand
Unmarshal method will help you easily convert stringified JSON to Go data types (mostly structs and maps)
https://i.stack.imgur.com/kW8ew.png
for more details, you can read the documentation:
https://golang.org/pkg/encoding/json/#Unmarshal
https://golang.org/pkg/encoding/json/#NewDecoder
https://golang.org/pkg/encoding/json/#Decoder.Decode
Although there are some good answers for it. I would like to summarize the difference between Encoding/decoding
and Marshaling/Unmarshaling
as below. Also some cases, you may use Encoding/decoding
, otherwise, Marshaling/Unmarshaling
could be used.
Encoding/decoding JSON refers to the process of actually reading/writing the character data to a string or binary form. Use NewEncoder when working with request or response bodies since they are Readers and it saves you a step of turning it into a byte array to use with Marshal The encoder also gives you some additional control like being able to error on unknown fields, which json.Unmarshal does not do. If you want indented JSON in some cases (by configurations, for example), then you can SetIndent(true). Also, the json.Encoder has SetEscapeHTML option
Use NewEncoder when working with request or response bodies since they are Readers and it saves you a step of turning it into a byte array to use with Marshal
The encoder also gives you some additional control like being able to error on unknown fields, which json.Unmarshal does not do.
If you want indented JSON in some cases (by configurations, for example), then you can SetIndent(true). Also, the json.Encoder has SetEscapeHTML option
Marshaling/Unmarshaling refers to mapping JSON types from and to Go data types and primitives.
Success story sharing