4. Marshal JSON

If there is a way to unmarshalarrow-up-right JSON data, there must be a way to marshal it as well. The json.Marshalarrow-up-right function converts a Go struct into a slice of bytes representing JSON data.

Example

type Board struct {
	Id       int    `json:"id"`
	Name     string `json:"name"`
	TeamId   int    `json:"team"`
	TeamName string `json:"team_name"`
}

board := Board{
	Id:       1,
	Name:     "API",
	TeamId:   9001,
	TeamName: "Backend",
}

data, err := json.Marshal(board)
if err != nil {
	log.Fatal(err)
}
fmt.Println(string(data))
// {"id":1,"name":"API","team":9001,"team_name":"Backend"}

πŸ“¦ The Simple Analogy

Think of JSON like a package you're shipping:

Marshaling = πŸ“¦ Packing (Go β†’ JSON) Unmarshaling = πŸ“­ Unpacking (JSON β†’ Go)


πŸ”„ Marshaling: Go Struct β†’ JSON String

"Marshal" means converting Go data into JSON format (for sending/storing).

Why? So you can:

  • Send it over the network (APIs)

  • Save it to a file

  • Store it in a database

  • Send it to a web browser


πŸ”„ Unmarshaling: JSON String β†’ Go Struct

"Unmarshal" means converting JSON into Go data (for reading/using).

Why? So you can:

  • Read data from an API response

  • Load configuration from a file

  • Process data sent from a web browser

  • Work with the data in your Go code


πŸ“Š Visual Comparison

MARSHALING (Packing) Go Struct ──────────> JSON String

UNMARSHALING (Unpacking) JSON String ──────────> Go Struct


🎯 Real-World Example

Scenario: Sending an email

Step: Marshal (before sending)

Step: Unmarshal (when receiving)


🧠 Memory Trick

Marshal = Mar-ching out (Go β†’ JSON, sending out) Unmarshal = Un-packing (JSON β†’ Go, bringing in)

Or think of it as:

  • Marshal = Make it transportable (like packing a suitcase)

  • Unmarshal = Make it usable (like unpacking a suitcase)


πŸ“ Quick Reference

Operation
Direction
Purpose
Example

Marshal

Go β†’ JSON

Convert to send/store

json.Marshal(struct)

Unmarshal

JSON β†’ Go

Convert to use in code

json.Unmarshal(json, &struct)


βœ… Summary

  • Marshal: Turn Go data into JSON (for sending/storing)

  • Unmarshal: Turn JSON into Go data (for using in your code)

Think:

  • Sending an email? Marshal it first

  • Receiving an email? Unmarshal it to read

Assignment

Complete the marshalAll function. It accepts a slice of "items", which can be of any type. The expectation is that they are structs of various forms. It should return a slice of slices of bytes [][]byte.

1

Create a slice of byte slices to hold the marshalled data.

2

For each item in items:

  • Marshal the item into a slice of bytes.

  • If an item cannot be marshaled, immediately return a nil slice and the error.

  • Add the marshalled JSON byte slice to the slice of bytes slices.

3

Return the marshalled data in the same order as the input items.

chevron-rightSolutionhashtag

Explanation of a key line:

  • make creates a slice.

  • [][]byte is the element type: a slice whose elements are []byte (each []byte will hold one marshaled JSON blob).

  • The second argument 0 is the length: the slice starts empty, so len(bs) == 0.

  • The third argument len(items) is the capacity: it pre-allocates space for that many elements, so appending up to len(items) times won’t need to grow the underlying array.

So you still append each data, but you avoid extra allocations/copies as the slice grows.