0

I have a string in my Go module which is the body of a HTTP response. it looks something like this:

bodyString = `{"firstname": "foo", "lastname": "bar", "username": "foobar"}`

I want to convert it to the following Go struct:

type Params struct {
  FirstName string
  LastName string
  Username string
  PasswordHash string 
  EmailAddress string
}

I attempt to do so using the following:

var jsonMap map[string]interface{}
json.Unmarshal([]byte(bodyString), &jsonMap)

paramsIn.FirstName = jsonMap["firstname"].(string)
paramsIn.LastName = jsonMap["lastname"].(string)
paramsIn.Username = jsonMap["username"].(string)
paramsIn.PasswordHash = jsonMap["passwordhash"].(string)
paramsIn.EmailAddress = jsonMap["emailaddress"].(string)

However the unmarshal fails to match the data in the string to the appropriate keys. i.e. what is stored in the jsonMap variable is only empty strings.

I clearly am doing something wrong and I haven't worked with json in Go very much. If any one can help or show me the correct way to unmarshal json data from a string that would be great, thanks.

3
  • 3
    Did you take a look at the error returned by Unmarshal? Commented Aug 1, 2022 at 6:14
  • 2
    Check the error returned from json.Unmarshal. Also, unmarshal directly to a value of type Params. go.dev/play/p/xL2Fc4St8wq Commented Aug 1, 2022 at 6:15
  • Always check errors! The OP reports in an answer that the JSON is invalid. Commented Aug 1, 2022 at 18:34

4 Answers 4

2

Golang will convert your struct's field name (CammelCase) to snake_case (default). So, if you have struct like :

type Params struct {
  FirstName string
  LastName string
  Username string
  PasswordHash string 
  EmailAddress string
}

The JSON from the struct will be :

{
    "first_name":"bla",
    "last_name":"bla",
    "user_name":"bla",
    "password_hash":"ewedsads",
    "email_address":"[email protected]"
}

But you can customize the JSON field name by json tag, example :

type Params struct {
  FirstName string `json:"firstname"`
  LastName string `json:"lastname"`
  Username string `json:"username"`
  PasswordHash string `json:"passwordhash"`
  EmailAddress string `json:"emailaddress"`
}

Then you can change your code like this :

package main

import (
    "encoding/json"
    "fmt"
)

type Params struct {
    FirstName    string `json:"firstname"`
    LastName     string `json:"lastname"`
    Username     string `json:"username"`
    PasswordHash string `json:"passwordhash"`
    EmailAddress string `json:"emailaddress"`
}

func main() {
    paramsIn := Params{}
    bodyString := `{"firstname": "foo", "lastname": "bar", "username": "foobar"}`

    json.Unmarshal([]byte(bodyString), &paramsIn)
    fmt.Println(paramsIn)
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks mate, this is a good point that I didn't know but it didn't fix my problem. I did end up finding out what it was however, check my solution.
Please check my last update. Maybe it can solve your problem. Thanks!
0

Use go tag like this:

    type Params struct {
        FirstName    string `json:"firstname"`
        LastName     string `json:"lastname"`
        Username     string `json:"username"`
        PasswordHash string
        EmailAddress string
    }

Comments

0

This may not be the solution to everyone who is experience this problem, and you should check out the other answers on this post and other similar SO posts.

For me the issue was how the double quote character was being treated ("). My json string was being created from the body of a http response, which was being fed by a curl command in another terminal window. I was writing my curl commands in MacOS's standard text editor but I was in RTF (Rich Text Format) which formatted my " character as something else () (The difference is miniscule but it was enough to completely stump me for hours!). There is no issue with the code above once I used the proper double quote character in the http request body.

If I am unclear, please comment and I can clarify more.

Comments

0

In my case the mistake was passing a bool with quotes, i. e. "stream":"false" instead of "stream":false.

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.