Search code examples
jsongo

How to convert JSON body to Golang types?


I have used this tool - https://mholt.github.io/json-to-go/ - to convert JSON body to Golang structure.

Input JSON

{
    "name": "my_dns",
    "servername": "example.com",
    "allow": [
        {
            "ip": "10.132.146.79",
            "port": "5555"
        }
    ],
    "restrict": [
        {
            "ip": "10.132.146.134",
            "port": "2323"
        }
    ],
    "deny": [
        {
            "ip": "10.132.146.201",
            "port": "10001"
        }
    ]
}

Corresponding Golang types

type AutoGenerated struct {
    Name       string     `json:"name,omitempty"`
    Servername string     `json:"servername,omitempty"`
    Allow      []Allow    `json:"allow,omitempty"`
    Restrict   []Restrict `json:"restrict,omitempty"`
    Deny       []Deny     `json:"deny,omitempty"`
}
type Allow struct {
    IP   string `json:"ip,omitempty"`
    Port string `json:"port,omitempty"`
}
type Restrict struct {
    IP   string `json:"ip,omitempty"`
    Port string `json:"port,omitempty"`
}
type Deny struct {
    IP   string `json:"ip,omitempty"`
    Port string `json:"port,omitempty"`
}

Question

Is there not a way where I can define :

type PortIP struct {
    IP   string `json:"ip,omitempty"`
    Port string `json:"port,omitempty"`
}

And use the above type in AutoGenerated:

type AutoGenerated struct {
    Name       string     `json:"name,omitempty"`
    Servername string     `json:"servername,omitempty"`
    Allow      []PortIP   `json:"allow,omitempty"`
    Restrict   []PortIP   `json:"restrict,omitempty"`
    Deny       []PortIP   `json:"deny,omitempty"`
}

How can I parse my JSON body request (the input is strictly supposed to be like that) effectively in Golang?


Solution

  • To parse a json input, you can use https://pkg.go.dev/encoding/json

    The types you provide seem correct, a complete (minimalistic) example :

    package main
    
    import (
        "encoding/json"
        "fmt"
        "log"
    )
    
    type PortIP struct {
        IP   string `json:"ip,omitempty"`
        Port string `json:"port,omitempty"`
    }
    
    type IPRule struct {
        Name       string   `json:"name,omitempty"`
        Servername string   `json:"servername,omitempty"`
        Allow      []PortIP `json:"allow,omitempty"`
        Restrict   []PortIP `json:"restrict,omitempty"`
        Deny       []PortIP `json:"deny,omitempty"`
    }
    
    func main() {
        data := []byte(`
    {
        "name": "my_dns",
        "servername": "example.com",
        "allow": [
            {
                "ip": "10.132.146.79",
                "port": "5555"
            }
        ],
        "restrict": [
            {
                "ip": "10.132.146.134",
                "port": "2323"
            }
        ],
        "deny": [
            {
                "ip": "10.132.146.201",
                "port": "10001"
            }
        ]
    }`)
    
        var parsed IPRule
        if err := json.Unmarshal(data, &parsed); err != nil {
            log.Fatal("Failed to parse JSON", err)
        }
    
        fmt.Println(parsed)
    }
    

    Hope it helps.