majidarif majidarif - 3 months ago 26
JSON Question

Golang constant struct key

In PHP we can do something like:

if ($env == "dev")
define("key", "key")
else
define("key", "secret")

// json ouput
//{ key : "value" } or { secret : "value" }


How do I properly translate above PHP approach to GO?

I was thinking of something like:

if *env == "dev" {
type response struct {
key string
...50 more keys that should also be different depending on env
}
} else {
secret string
...50 more keys...
}


But I guess that is not only wrong but would also create a huge repeated code...

Answer

You may create a struct type holding the common part of your data structure, and you may create new types embedding this and only adding the deviating new field. So there is no code repetition of the common part of the data structure:

type Response struct {
    F1 string
    F2 int
}

func main() {
    for _, env := range []string{"dev", "prod"} {
        if env == "dev" {
            type Resp struct {
                Response
                Key string
            }
            r := Resp{Response{"f1dev", 1}, "value"}
            json.NewEncoder(os.Stdout).Encode(r)
        } else {
            type Resp struct {
                Response
                Secret string
            }
            r := Resp{Response{"f1pro", 2}, "value"}
            json.NewEncoder(os.Stdout).Encode(r)
        }
    }
}

Output (try it on the Go Playground):

{"F1":"f1dev","F2":1,"Key":"value"}
{"F1":"f1pro","F2":2,"Secret":"value"}

Note that you may also use the same Response value if they are the same for the 2 use cases:

comResp := Response{"f1value", 1}
if env == "dev" {
    type Resp struct {
        Response
        Key string
    }
    r := Resp{comResp, "value"}
    json.NewEncoder(os.Stdout).Encode(r)
} else {
    type Resp struct {
        Response
        Secret string
    }
    r := Resp{comResp, "value"}
    json.NewEncoder(os.Stdout).Encode(r)
}

You may shorten the code above by using anonymous struct and not creating a local variable (not necessarily more readable):

if env == "dev" {
    json.NewEncoder(os.Stdout).Encode(struct {
        Response
        Key string
    }{comResp, "value"})
} else {
    json.NewEncoder(os.Stdout).Encode(struct {
        Response
        Secret string
    }{comResp, "value"})
}