AppDividend
Latest Code Tutorials

Golang: How To Serialize JSON String in Go Example

Golang json.Marshal() function returns the JSON encoding of interface. Marshal traverses the value of interface recursively. If an encountered value implements the Marshaler interface and is not a nil pointer, Marshal calls its MarshalJSON method to produce JSON.

Golang Serialize JSON String

See the following code.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
)

// Tesla struct
type Tesla struct {
	ProductName  string `json:"productName"`
	ProductPrice string `json:"productPrice"`
}

func main() {
	in := `{"productName":"CyberTruck","productPrice": 39900}`

	bytes, err := json.Marshal(in)
	if err != nil {
		panic(err)
	}

	var t Tesla
	err = json.Unmarshal(bytes, &t)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v", t)
}

Output

go run hello.go
panic: json: cannot unmarshal string into Go value of type main.Tesla

goroutine 1 [running]:
main.main()
	/Users/krunal/Desktop/code/go/src/hello/hello.go:25 +0x1d8
exit status 2

So, it will panic and returns an error.

Now, write the following code to see what’s exactly going on.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
)

// Tesla struct
type Tesla struct {
	ProductName  string `json:"productName"`
	ProductPrice string `json:"productPrice"`
}

func main() {
	in := `{"productName":"CyberTruck","productPrice": 39900}`

	bytes, err := json.Marshal(in)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))
}

Output

go run hello.go
"{\"productName\":\"CyberTruck\",\"productPrice\": 39900}"

When we convert JSON string to usual string, then it does escape the double quotes that is why it returns an error.

So, how to skip escaping?

Well, we have two solutions to correctly Serialize JSON string.

  1. Use []byte()
  2. Use json.RawMessage()

Golang []byte

Golang byte is the alias for uint8 and is equivalent to uint8 in all ways. The byte is used, by convention, to distinguish the byte values from 8-bit unsigned integer values.

See the following code.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
)

// Tesla struct
type Tesla struct {
	ProductName  string `json:"productName"`
	ProductPrice string `json:"productPrice"`
}

func main() {

	data := `{"productName":"CyberTruck","productPrice":"39900"}`
	bytes := []byte(data)
	var t Tesla
	err := json.Unmarshal(bytes, &t)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v \n", t)
	fmt.Println(string(bytes))
}

Output

go run hello.go
{ProductName:CyberTruck ProductPrice:39900}
{"productName":"CyberTruck","productPrice":"39900"}

In the above program, we have converted json to a byte array. So it prevents the double quotes from escaping, and then we have used json.Unmarshal() function.

Golang json.RawMessage()

Golang json package includes a solution for the issue. Golang json has RawMessage type, which Marshalls and Unmarshals without escaping.

So if you need to serialize the JSON string which you need to deserialize later into a struct, do it with json.RawMessage().

See the following code example.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
)

// Tesla struct
type Tesla struct {
	ProductName  string `json:"productName"`
	ProductPrice string `json:"productPrice"`
}

func main() {

	data := `{"productName":"CyberTruck","productPrice":"39900"}`
	rawData := json.RawMessage(data)
	bytes, err := rawData.MarshalJSON()
	if err != nil {
		panic(err)
	}

	var t Tesla
	err = json.Unmarshal(bytes, &t)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v \n", t)
	fmt.Println(string(bytes))
}

Output

go run hello.go
{ProductName:CyberTruck ProductPrice:39900}
{"productName":"CyberTruck","productPrice":"39900"}

It returns the same output.

RawMessage is a raw encoded JSON value. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding. MarshalJSON returns RawMessage as the JSON encoding of RawMessage.

Serialized struct

The serialized struct is identical to our JSON string.

Now, Let’s make sure that JSON string matches Tesla struct.

See the following code.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
)

// Tesla struct
type Tesla struct {
	ProductName  string `json:"productName"`
	ProductPrice string `json:"productPrice"`
}

func main() {

	bytes, err := json.Marshal(Tesla{
		ProductName:  "CyberTruck",
		ProductPrice: "39900",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))
}

Output

go run hello.go
{"productName":"CyberTruck","productPrice":"39900"}

Conclusion

So, the Serialized struct works fine with json.Marshal() function but serialized json string directly does not support Marshal() because it escapes double-quotes. So to avoid that, we can use []byte or json.RawMessage() function.

If you want to Serialize JSON String In Golang Correctly, then this is a perfect way.

Finally, Golang Serialize JSON String example is over.

See also

Golang string to int

Golang JSON to Map

Golang String to byte array

Golang int to string

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.