9.1. JSON

While implementing your client app, you will want perform a variety of operations on data represented by Go stucts. For example, save/load data to/from Datastore, or using any of the provided Cryptographic Functions.

All of these functions require byte slices and cannot operate directly on Go structs. To transform a Go struct into a byte slice, you will serialize the Go struct into JSON using the Go JSON library, which is already imported into proj2.go.

In particular, you will want to use the following these two functions:

json.Marshal(v interface{}) ([]byte, err)
  • Converts an arbitrary Go value into a byte slice containing the JSON representation of the struct.

  • Only public fields are converted. Private fields (fields starting with a lowercase letter) are not marshaled into the output.

  • This function will automatically follow pointers and nested pointers when marshalling.

Parameters

v (interface{}) – Value to be converted into JSON. This can be any data type.

Return type

[]byte, err

Examples:

uid := uuid.New()
d, _ := json.Marshal(uid)
// d is a []byte which can be converted easily back into a UUID
type User struct {
    Username string
    Password string
    secret   int
}

alice := &User{
    "alice",
    "password",
    42,
}
bytes, _ := json.Marshal(alice)
userlib.DebugMsg("%s\n", string(bytes))
// {"Username":"alice","Password":"password"}
json.Unmarshal(v []byte, obj interface{}) (error)
  • Converts a byte slice generated by json.Marshal back into a Go struct.

  • Public fields are restored if present, and private fields will be default-initialized.

  • This function automatically generates nested pointers where needed to generate a valid struct.

  • This function will return an error if there is a type mismatch between the JSON and the struct (e.g. storing a string into a number field in a struct).

Parameters
  • v ([]byte) – Output from a call to json.Marshal

  • obj (interface{}) – Pointer to the Go struct where values will be loaded

Return type

error

Examples:

uid := uuid.New()
d, _ := json.Marshal(uid)
var result UUID
err := json.Unmarshal(d, &result)
if err != nil {
    // Error! handle me
}
// Now you can use result as with any other struct variable in Go.
type User struct {
    Username string
    Password string
    secret   int
}
bytes := []byte("{\"Username\":\"alice\",\"Password\":\"password\"}")
var alice User;
json.Unmarshal(bytes, &alice)
userlib.DebugMsg("%v\n", alice)
// {alice password 0}