Source From Here
PrefaceWelcome all, in this tutorial, we are going to be taking a look at how you can read in JSON files, or JSON HTTP responses and parse them to your hearts desire.
JSON or Javascript Object Notation as it is short for, is a standard format for sending and receiving information. We could represent the same information with either XML or JSON, but JSON provides one advantage in the fact it is far more compact and in my personal experience, more readable.
JSON is now the most popular data format available and you’ll find that most RESTful APIs provide JSON responses when you try to interface with them. Thus being able to work with it and parse it in Go is incredibly useful!
The Encoding/Json Package
So, to get us started, we’ll be leveraging the encoding/json standard library package in order to get us up and running. I highly recommend you check out the official documentation for this here: Encoding/Json. Let’s start with a really simple Go program as our base, we’ll build this out to showcase how to work with various different examples. Create a new file called main.go:
- main.go
- package main
- import (
- "fmt"
- )
- func main() {
- fmt.Println("Hello World")
- }
Reading and Parsing a JSON File
Let’s try and read in a simple JSON file and then parse it. For the purpose of this tutorial we’ll be parsing the following json within our file. Copy this and save it into a users.json file within the same directory as your main.go file:
- user.json
- {
- "users": [
- {
- "name": "Elliot",
- "type": "Reader",
- "age": 23,
- "social": {
- "facebook": "https://facebook.com",
- "twitter": "https://twitter.com"
- }
- },
- {
- "name": "Fraser",
- "type": "Author",
- "age": 17,
- "social": {
- "facebook": "https://facebook.com",
- "twitter": "https://twitter.com"
- }
- }
- ]
- }
Reading the JSON File
We’ll be using the os package in order to open up our users.json file from our filesystem. Once we have opened the file, we’ll defer the closing of the file till the end of the function so that we can work with the data inside of it:
- // Open our jsonFile
- jsonFile, err := os.Open("users.json")
- // if we os.Open returns an error then handle it
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println("Successfully Opened users.json")
- // defer the closing of our jsonFile so that we can parse it later on
- defer jsonFile.Close()
We have a few options when it comes to parsing the JSON that is contained within our users.json file. We could either unmarshal the JSON using a set of predefined structs, or we could unmarshal the JSON using a map[string]interface{} to parse our JSON into strings mapped against arbitrary data types.
If you know the structure that you are expecting then I would recommend going down the verbose route and defining your structs like so:
- main.go
- package main
- import (
- …
- // import our encoding/json package
- “encoding/json”
- …
- )
- // Users struct which contains
- // an array of users
- type Users struct {
- Users []User `json:"users"`
- }
- // User struct which contains a name
- // a type and a list of social links
- type User struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Age int `json:"Age"`
- Social Social `json:"social"`
- }
- // Social struct which contains a
- // list of links
- type Social struct {
- Facebook string `json:"facebook"`
- Twitter string `json:"twitter"`
- }
Unmarshalling our JSON
Once we’ve used the os.Open function to read our file into memory, we then have to convert it to a byte array using ioutil.ReadAll. Once it’s in a byte array we can pass it to our json.Unmarshal() method:
- // read our opened jsonFile as a byte array.
- byteValue, _ := ioutil.ReadAll(jsonFile)
- // we initialize our Users array
- var users Users
- // we unmarshal our byteArray which contains our
- // jsonFile's content into 'users' which we defined above
- json.Unmarshal(byteValue, &users)
- // we iterate through every user within our users array and
- // print out the user Type, their name, and their facebook url
- // as just an example
- for i := 0; i < len(users.Users); i++ {
- fmt.Println("User Type: " + users.Users[i].Type)
- fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))
- fmt.Println("User Name: " + users.Users[i].Name)
- fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)
- }
Sometimes, going through the process of creating structs for everything can be somewhat time consuming and overly verbose for the problems you are trying to solve. In this instance, we can use standard interfaces{} in order to read in any JSON data:
- package main
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- )
- func main() {
- // Open our jsonFile
- jsonFile, err := os.Open("users.json")
- // if we os.Open returns an error then handle it
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println("Successfully Opened users.json")
- // defer the closing of our jsonFile so that we can parse it later on
- defer jsonFile.Close()
- byteValue, _ := ioutil.ReadAll(jsonFile)
- var result map[string]interface{}
- json.Unmarshal([]byte(byteValue), &result)
- fmt.Println(result["users"])
- }
If we wanted to traverse further down the tree, we could do that just as we normally would traverse down a map structure within Go, without having to define the struct types.
Full Implementation
Below you’ll find the full implementation of this tutorial:
- main.go
- package main
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "strconv"
- )
- // Users struct which contains
- // an array of users
- type Users struct {
- Users []User `json:"users"`
- }
- // User struct which contains a name
- // a type and a list of social links
- type User struct {
- Name string `json:"name"`
- Type string `json:"type"`
- Age int `json:"Age"`
- Social Social `json:"social"`
- }
- // Social struct which contains a
- // list of links
- type Social struct {
- Facebook string `json:"facebook"`
- Twitter string `json:"twitter"`
- }
- func main() {
- // Open our jsonFile
- jsonFile, err := os.Open("users.json")
- // if we os.Open returns an error then handle it
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println("Successfully Opened users.json")
- // defer the closing of our jsonFile so that we can parse it later on
- defer jsonFile.Close()
- // read our opened xmlFile as a byte array.
- byteValue, _ := ioutil.ReadAll(jsonFile)
- // we initialize our Users array
- var users Users
- // we unmarshal our byteArray which contains our
- // jsonFile's content into 'users' which we defined above
- json.Unmarshal(byteValue, &users)
- // we iterate through every user within our users array and
- // print out the user Type, their name, and their facebook url
- // as just an example
- for i := 0; i < len(users.Users); i++ {
- fmt.Println("User Type: " + users.Users[i].Type)
- fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))
- fmt.Println("User Name: " + users.Users[i].Name)
- fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)
- }
- }
* Creating a RESTful API with Go
* Creating a Simple Web Server with Go
沒有留言:
張貼留言