DEV Community

Cover image for Hey Marshal
bseyhan
bseyhan

Posted on

Hey Marshal

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
}
Enter fullscreen mode Exit fullscreen mode

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

Image description

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"}
Enter fullscreen mode Exit fullscreen mode

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
}   

Enter fullscreen mode Exit fullscreen mode

Image description

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)
Enter fullscreen mode Exit fullscreen mode

Image

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)

}   
Enter fullscreen mode Exit fullscreen mode

Real world example

In this example I'll request a public Web API. PublicAPI 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"`
}

Enter fullscreen mode Exit fullscreen mode

Next step is creating a web request. About 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)
Enter fullscreen mode Exit fullscreen mode

Image

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)
    }

Enter fullscreen mode Exit fullscreen mode

Image

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))
Enter fullscreen mode Exit fullscreen mode

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"
    }
  }
]
Enter fullscreen mode Exit fullscreen mode

Repository

Thank you.

Discussion (0)