Hey Marshal
Tags: go, tutorial, opensource, programming
Published: 2021-11-01 12:59:38

Hi everyone,

Before creating a project, let's simply talk about other issue. What is Json, Struct, Marshall & UnMarshall. In this document, I'll introduce Json to Struct and apposite of it. How to make a request and how to convert it. What are these required packages? A struct is a user-defined type that represent a collection of field. If you write C# code before you might remember it. Well let's start. First in first how to define a simple struct.

```
type Users struct{}

type Customers struct{}

type Students struct{
    FirstName string
    LastName  string
}
```

Let's create a new GoLang project and run it.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r02qjo6knetgh6fphzc6.png)
 
### Create Student Struct
```
type Student struct{
	FirstName string 
	LastName  string
}

type Company struct{
	Name string `json:"name"`
	Address  string `json:"address"`
}

//initialize
student := Student{FirstName:"Burak", LastName:"Seyhan"}
```

Your application has already it. You don't run go get -u command.

# Marshal()

Converting Go objects into JSON is called Marshal() in GoLang. As the JSON is a language-independent data format.

```
package main

import (
	"fmt"
	"encoding/json"
)

type Student struct{
	FirstName string
	LastName  string
}

func main()  {
	fmt.Println("Welcome to Json and Struct Implementation")

	//initialize
	student := Student{FirstName:"Burak", LastName:"Seyhan"}

	data, err := json.Marshal(student)
	if(err != nil){
		fmt.Println(err)
	}

	fmt.Println(data) // data is byteArray
	fmt.Println(string(data)) convert to byteArray to string
}	

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wk4i9qp9agrqm8a753st.png)

# UnMarshal()

Unmarshalling just opposite of Marshal. 

```
var unmarshalStudent Student
unmarshal := json.Unmarshal([]byte(data), &unmarshalStudent)

if(unmarshal != nil){
	fmt.Println(unmarshal)
}

fmt.Printf("%v+\n", data)
```
 
![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1dfqkndpghwviy7b4lt.png)

Full code
```
package main

import (
	"fmt"
	"encoding/json"
)

type Student struct{
	FirstName string `json:"firtname"`
	LastName  string `json:"lastnamename"`
}


func main()  {
	fmt.Println("Welcome to Json and Struct Implementation")

	
	//initialize
	student := Student{FirstName:"Burak", LastName:"Seyhan"}

	data, err := json.Marshal(student)
	if(err != nil){
		fmt.Println(err)
	}

	fmt.Println(data)
	fmt.Println(string(data))


	var unmarshalStudent Student
	unmarshal := json.Unmarshal([]byte(data), &unmarshalStudent)
	if(unmarshal != nil){
		fmt.Println(unmarshal)
	}
	fmt.Printf("%v+\n", data)
	
}	
```

# Real world example

In this example I'll request a public Web API. [PublicAPI](https://jsonplaceholder.typicode.com/users) This end point related with some user informations. At the beginning I'm gonna create a Struct.

```
type Users struct{
	Id int `json:"id"`
	Name  string `json:"name"`
	UserName  string `json:"username"`
	Email  string `json:"email"`
	Address  Address `json:"address"`
	Phone  string `json:"phone"`
	Website  string `json:"website"`
	Company  Company `json:"company"`
}

type Address struct{
	Street  string `json:"street"`
	Suite  string `json:"suite"`
	City  string `json:"city"`
	Zipcode  string `json:"zipcode"`
}

type Company struct{
	Name  string `json:"name"`
	CatchPhrase  string `json:"catchPhrase"`
	Bs  string `json:"bs"`
}

```

Next step is creating a web request. [About net/http](https://pkg.go.dev/net/http)

```
	//endpoint
	url := "https://jsonplaceholder.typicode.com/users"

	//create a client
	client := http.Client{
		Timeout: time.Second * 2, // Timeout after 2 seconds
	}

	//prepera new request s
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if(err != nil){
		fmt.Println(err)
	}

	result , getErr:= client.Do(req)
	if(getErr != nil){
		fmt.Println(getErr)
	}
	fmt.Println(result)
```

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btts5wkmx53x58ohupoh.png)

The defer keyword which executes result.Body.Close() at the end of the function is used to close the response body. 

```
if(result.Body != nil){
		defer result.Body.Close()
	}

	body, _ := ioutil.ReadAll(result.Body)
    
	users := []Users{} // declare array cause Json data is array

	jsonErr := json.Unmarshal(body, &users)

	if(jsonErr != nil){
		fmt.Println(jsonErr)
	}

	for _, data := range users{
		fmt.Println(data)
	}

```
 
![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owvy01andvtmf09twbpv.png)
 

### packages
These packages are loaded by default you don't need a go get command

* "fmt"
* "net/http"
* "time"
* "io/ioutil"
* "encoding/json"

"fmt" package using for display some information or get any inputs from client but if you don't wanna use "fmt" code is Println("") because GoLang come with default packages. "net/http" packages is Web Request packages same as "fmt" package. "time" packages related to time information like DateTime. In this example doesn't need to this. You don't have to set Timeout actually it depends on. To get the response we are interested in, we have to access the Body property why we use "io/ioutil" packages. "encoding/json" packages related with marshal and unmarshal functions.


## Another usage 

```
url := "https://jsonplaceholder.typicode.com/users"

resp, err := http.Get(url)
if err != nil {
   fmt.Println(err)
}
  
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
    fmt.Println(err)
}

fmt.Println(string(body))
```
Now run `go run main.go` see results:

```
[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },
  {
    "id": 3,
    "name": "Clementine Bauch",
    "username": "Samantha",
    "email": "Nathan@yesenia.net",
    "address": {
      "street": "Douglas Extension",
      "suite": "Suite 847",
      "city": "McKenziehaven",
      "zipcode": "59590-4157",
      "geo": {
        "lat": "-68.6102",
        "lng": "-47.0653"
      }
    },
    "phone": "1-463-123-4447",
    "website": "ramiro.info",
    "company": {
      "name": "Romaguera-Jacobson",
      "catchPhrase": "Face to face bifurcated interface",
      "bs": "e-enable strategic applications"
    }
  },
  {
    "id": 4,
    "name": "Patricia Lebsack",
    "username": "Karianne",
    "email": "Julianne.OConner@kory.org",
    "address": {
      "street": "Hoeger Mall",
      "suite": "Apt. 692",
      "city": "South Elvis",
      "zipcode": "53919-4257",
      "geo": {
        "lat": "29.4572",
        "lng": "-164.2990"
      }
    },
    "phone": "493-170-9623 x156",
    "website": "kale.biz",
    "company": {
      "name": "Robel-Corkery",
      "catchPhrase": "Multi-tiered zero tolerance productivity",
      "bs": "transition cutting-edge web services"
    }
  },
  {
    "id": 5,
    "name": "Chelsey Dietrich",
    "username": "Kamren",
    "email": "Lucio_Hettinger@annie.ca",
    "address": {
      "street": "Skiles Walks",
      "suite": "Suite 351",
      "city": "Roscoeview",
      "zipcode": "33263",
      "geo": {
        "lat": "-31.8129",
        "lng": "62.5342"
      }
    },
    "phone": "(254)954-1289",
    "website": "demarco.info",
    "company": {
      "name": "Keebler LLC",
      "catchPhrase": "User-centric fault-tolerant solution",
      "bs": "revolutionize end-to-end systems"
    }
  },
  {
    "id": 6,
    "name": "Mrs. Dennis Schulist",
    "username": "Leopoldo_Corkery",
    "email": "Karley_Dach@jasper.info",
    "address": {
      "street": "Norberto Crossing",
      "suite": "Apt. 950",
      "city": "South Christy",
      "zipcode": "23505-1337",
      "geo": {
        "lat": "-71.4197",
        "lng": "71.7478"
      }
    },
    "phone": "1-477-935-8478 x6430",
    "website": "ola.org",
    "company": {
      "name": "Considine-Lockman",
      "catchPhrase": "Synchronised bottom-line interface",
      "bs": "e-enable innovative applications"
    }
  },
  {
    "id": 7,
    "name": "Kurtis Weissnat",
    "username": "Elwyn.Skiles",
    "email": "Telly.Hoeger@billy.biz",
    "address": {
      "street": "Rex Trail",
      "suite": "Suite 280",
      "city": "Howemouth",
      "zipcode": "58804-1099",
      "geo": {
        "lat": "24.8918",
        "lng": "21.8984"
      }
    },
    "phone": "210.067.6132",
    "website": "elvis.io",
    "company": {
      "name": "Johns Group",
      "catchPhrase": "Configurable multimedia task-force",
      "bs": "generate enterprise e-tailers"
    }
  },
  {
    "id": 8,
    "name": "Nicholas Runolfsdottir V",
    "username": "Maxime_Nienow",
    "email": "Sherwood@rosamond.me",
    "address": {
      "street": "Ellsworth Summit",
      "suite": "Suite 729",
      "city": "Aliyaview",
      "zipcode": "45169",
      "geo": {
        "lat": "-14.3990",
        "lng": "-120.7677"
      }
    },
    "phone": "586.493.6943 x140",
    "website": "jacynthe.com",
    "company": {
      "name": "Abernathy Group",
      "catchPhrase": "Implemented secondary concept",
      "bs": "e-enable extensible e-tailers"
    }
  },
  {
    "id": 9,
    "name": "Glenna Reichert",
    "username": "Delphine",
    "email": "Chaim_McDermott@dana.io",
    "address": {
      "street": "Dayna Park",
      "suite": "Suite 449",
      "city": "Bartholomebury",
      "zipcode": "76495-3109",
      "geo": {
        "lat": "24.6463",
        "lng": "-168.8889"
      }
    },
    "phone": "(775)976-6794 x41206",
    "website": "conrad.com",
    "company": {
      "name": "Yost and Sons",
      "catchPhrase": "Switchable contextually-based project",
      "bs": "aggregate real-time technologies"
    }
  },
  {
    "id": 10,
    "name": "Clementina DuBuque",
    "username": "Moriah.Stanton",
    "email": "Rey.Padberg@karina.biz",
    "address": {
      "street": "Kattie Turnpike",
      "suite": "Suite 198",
      "city": "Lebsackbury",
      "zipcode": "31428-2261",
      "geo": {
        "lat": "-38.2386",
        "lng": "57.2232"
      }
    },
    "phone": "024-648-3804",
    "website": "ambrose.net",
    "company": {
      "name": "Hoeger LLC",
      "catchPhrase": "Centralized empowering task-force",
      "bs": "target end-to-end models"
    }
  }
]
```

[Repository](https://github.com/bburaksseyhan/workingjson.git)

Thank you.