6

Below is the actual struct type in aws go sdk elbv2 package. There are other parameters in this struct. I have kept only the necessary ones for simplicity.

type CreateTargetGroupInput struct {
    _ struct{} `type:"structure"`
    Name *string `type:"string" required:"true"`
    Port *int64 `min:"1" type:"integer" required:"true"`
    Protocol *string `type:"string" required:"true" enum:"ProtocolEnum"`
    VpcId *string `type:"string" required:"true"`
}  

I need to decode a JSON string with integer number like:

{ "name": "test-tg", "port": "8080", "protocol": "HTTP" ,"vpcId": "vpc-xxxxxx"}

go code:

func main() {
    s := `{ "name": "test-tg", "port": "8080", "protocol": "HTTP" ,"vpcId": "vpc-xxxxxx"}`

    targetGroupInput := &elbv2.CreateTargetGroupInput{}
    err := json.Unmarshal([]byte(s), targetGroupInput)

    if err == nil {
        fmt.Printf("%+v\n", targetGroupInput)
    }
}

I'm getting the below output, (if I pass port in integer format it'll work)

{
    Name: "testTG",
    Port: 0,
    Protocol: "HTTP",
    VpcId: "vpc-0f2c8a76"
}

My question is there is no json field in the original struct, so whatever valid name I pass as json field, it is still maaping to go field. i.e. I can send Name field as

"name, Name, NamE, etc" 

in json and it still works.

I'm confused here. For other user defined struct it wont map properly if I don't provide valid json name as defined against that go field.

Also how do I convert Port to integer from string during Json Unmarshlling?

As of now I'm using the exact copy of the struct in my project and removing the string type to integer for all integer type fields (also removed all pointers from all struct fields) and receiving the json object and I'm then converting it to integer and making the object of original struct.

It takes more time for me to maintain the exact copy by doing some changes in my project folder and to do validation against all such parameters.

I have the following questions.

  1. Is there a way to convert string to integer during unmarshlling without adding json tag like (json:",string") against the integer field.
  2. Is it a good practice to maintain an exact copy of the struct (struct of elbv2 package) with few changes?
6
  • Json tags are used to store meta information. Basically when you are using json.Marshal it will by default takes the capital case field names of struct but if you are using json tags you will get different json ouput on marshalling. Commented Mar 4, 2018 at 16:42
  • I'm getting proper o/p for this go struct CreateTargetGroupInput even though there is no json tag present .. also I can send the json name however I want as long as the name is correct in this case.. I can send Port as port, PorT, PORT, PoRT, etc. that's where my confusion is.. for normal struct it won't allow Commented Mar 4, 2018 at 16:53
  • One thing what I observed is, I have declared targetGroupInput (targetGroupInput := &elbv2.CreateTargetGroupInput{} ) as pointer and it works for all structs, no matter what json tag you give as long as parameter spelling remains same. Commented Mar 4, 2018 at 16:56
  • yes it works like that but the change comes when you are marshalling the json which will name the json tag on basis of your struct field name or json tag if defined. Commented Mar 4, 2018 at 17:03
  • Yes, Himanshu I agree that during Marshalling it give either Capital case field or the name defined in json tag. Also it is the same for Unmarshalling if the object if not a struct pointer. I have updated the question. Please let me know if you have any idea on it. Commented Mar 4, 2018 at 17:13

3 Answers 3

10

To convert from string to int64 simply tell Go that its a string encoded int64.

type CreateTargetGroupInput struct {
    _ struct{} `type:"structure"`
    Name *string `type:"string" required:"true"`
    Port *int64 `json:",string"`
    Protocol *string `type:"string" required:"true" enum:"ProtocolEnum"`
    VpcId *string `type:"string" required:"true"`
}

from: https://golang.org/pkg/encoding/json

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, but it is not a best practise to do the changes on the original struct of the aws go sdk. if there is no other way then I have to maintain a exact copy of the struct in my project with some little changes right
@k_vishwanath. No you don't. You have your own struct which matches the JSON you receive to unmarshal the JSON and you copy the value to the struct provided by the AWS sdk. Different things, different struct. Where's the problem with a little programming?
@Volker. I'm already maintaining the copy of the SDK struct and using it. Thank you
4

You can use the json.Number data type to convert the string to an integer value.

struct

type CreateTargetGroupInput struct {
    _        struct{}    `type:"structure"`
    Name     string      `type:"string" required:"true"`
    Port     json.Number `min:"1" type:"integer" required:"true"`
    Protocol string      `type:"string" required:"true" enum:"ProtocolEnum"`
    VpcId    string      `type:"string" required:"true"`
}

go code


func main() {
    s := `{ "name": "test-tg", "port": "8080", "protocol": "HTTP" ,"vpcId": "vpc-xxxxxx"}`

    var targetGroupInput CreateTargetGroupInput
    err := json.Unmarshal([]byte(s), &targetGroupInput)

    if err == nil {
        fmt.Printf("%+v\n", targetGroupInput)
    }
}

output

{
    "Name": "test-tg",
    "Port": 8080,
    "Protocol": "HTTP",
    "VpcId": "vpc-xxxxxx"
}

Reference: https://play.golang.org/p/3q4-CGnmNyE

Comments

-1

We can define any name whether lower or upper case when unmarshal the json bytes to a struct. But we cannot define it when marshaling the struct to json. As It will not convert the lower case field name It will not take the value of json since the name should be uppercase for it to become exportable. Check this code on Go playground

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.