CS 245 - Programming Languages

Lab 6

Go and JSON

JSON (JavaScript Object Notation) is the de-facto standard for data serialization. The uses of JSON go far beyond JavaScript. In this lab you will learn about JSON and how to unmarshal (convert from JSON into Go structs) and marshal (convert from Go Structs into JSON) JSON in Go

JSON

Start the lab by learning about JSON. One of the best resources is https://www.json.org/json-en.html, which is correct and complete but rather hard to read. Lots of other web resources are available. Many are actually readable.

Write a JSON file -- you can do so in VSC (create a file xxx.json) -- containing data about 3 fictional Bi-Co students. The file should contain at least the following information for each student:

  1. First Name
  2. Last Name
  3. Id -- as a string
  4. Age -- as in integer
  5. DateOfBirth (see below)
  6. FavoriteRealNumber -- as a number
The file should be arranged as a JSON array of JSON objects.

Date of birth should itself be a JSON object with the following fields:
  1. Year -- an integer
  2. Month -- a string
  3. Day -- an integer

JSON and Go

Because JSON is a de-facto standard, Go has a package for reading and writing json data. So first, open the file you just made for reading and read the entire contents into an array of bytes.
        jsonFile, err := os.Open("bico.json")
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println("Successfully Opened bico.json")
        byteValue, _ := ioutil.ReadAll(jsonFile)
        jsonFile.Close()
    
My experience with opening files is that if you use the the "run" button in VSC, you need to give the full, absolute path to the file being opened. If you use a terminal window and type "go run xx.go" then you can use a relative path name. (As a aside, what "go run ..." actually seems to do is to run "go build ..." and put the compiled executable into a file somewhere in the /tmp directory and then run that compiled file. When VSC does this, it actually seems to switch the current directory away from where the source is. Hence, the need to use absolute paths. )

Once read, the simplest thing to do is to unmarshal the byte array into a slice of maps. To do so create two types
        type jsonMap map[string]interface{}
        type jsonSlice []jsonMap
    
then after the read function add the following lines:
        var res jsonSlice
        json.Unmarshal(byteValue, &res)    
    
Done. You have read in the JSON file. Add a print statement to verify that you have succeeded.

Unmarshalling into structs

Read the web page hhttps://www.restapiexample.com/golang-tutorial/marshal-and-unmarshal-of-struct-data-using-golang/ . This gives a good overview of unmarshalling JSON directly into an array of Go structs.

Create structs as needed to read your student data file. You may want to update the representation in your JSON to make this easier. Then adjust your code to read the JSON into a slice of structs.

One important thing when you are creating structs for unmarshalling. The variable names inside the structs MUST have an initial capital letter. Why?

Marshall back to JSON

Finally, take the result of reading your student data into structs and produce new JSON by marshalling.
        data, _ := json.Marshal(students)
	    fmt.Println(string(data))
    
The resulting JSON should be fairly similar to your student file.

What to hand in

Send your JSON student data and your final go program to gtowell@brynmawr.edu