I send Json data with net/http package by an Url, i want to have some lowercase keys in return, but it's not working.
In this example of the problem, i want lowercase 'count' and 'data' key.
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type tableau struct {
Count int `json"count"`
Data []People `json"data"`
}
type People struct {
Id int `json"Id"`
Name string `json"Name"`
Age int `json"Age"`
}
func main() {
http.HandleFunc("/people", recupPeople)
fs := http.FileServer(http.Dir("Static"))
http.Handle("/", fs)
http.ListenAndServe(":80", nil)
}
func recupPeople(w http.ResponseWriter, r *http.Request) {
listPeople := &tableau{
Count: 4,
Data: []People{
People{Id: 1, Name: "Laurent", Age: 20},
People{Id: 2, Name: "Laurent", Age: 20},
},
}
peop, _ := json.Marshal(listPeople)
fmt.Println(string(peop))
w.Write(peop)
json.NewEncoder(w).Encode(listPeople)
}
But when i check the URL i didn't have lower case.
Cordially,
Laurent
You forgot colon in tag declaration. As tags are not in proper format, field names are in your json.
Try this:
type tableau struct {
Count int `json:"count"`
Data []People `json:"data"`
}
Try adding a : to your struct tags:
type tableau struct {
Count int `json:"count"`
Data []People `json:"data"`
}
Related
I try to replicate this body form in order to use it in a request:
{"Responses":[{"type":"DROP_DOWN","value":"0"}]}
so what im doing is :
type FruitBasket struct {
Name5 []string `json:"Responses"`
}
form := payload{
Name5: []string{"type", "value"},
}
jsonData, err := json.Marshal(form)
fmt.Println(string(jsonData))
But i can't find a way to complete the body in the brackets
You need to use the Unmarshal function from "encoding/json" package and use a dummy struct to extract the slice fields
// You can edit this code!
// Click here and start typing.
package main
import (
"encoding/json"
"fmt"
)
func main() {
str := `{"Responses":[{"type":"DROP_DOWN","value":"0"}]}`
type Responses struct {
Type string `json:"type"`
Value string `json:"value"`
}
// add dummy struct to hold responses
type Dummy struct {
Responses []Responses `json:"Responses"`
}
var res Dummy
err := json.Unmarshal([]byte(str), &res)
if err != nil {
panic(err)
}
fmt.Println("%v", len(res.Responses))
fmt.Println("%s", res.Responses[0].Type)
fmt.Println("%s", res.Responses[0].Value)
}
JSON-to-go is a good online resource to craft Go date types for a particular JSON schema.
Pasting your JSON body & extracting out the nested types you could use the following types to generate the desired JSON schema:
// types to produce JSON:
//
// {"Responses":[{"type":"DROP_DOWN","value":"0"}]}
type FruitBasket struct {
Response []Attr `json:"Responses"`
}
type Attr struct {
Type string `json:"type"`
Value string `json:"value"`
}
to use:
form := FruitBasket{
Response: []Attr{
{
Type: "DROP_DOWN",
Value: "0",
},
}
}
jsonData, err := json.Marshal(form)
working example: https://go.dev/play/p/SSWqnyVtVhF
output:
{"Responses":[{"type":"DROP_DOWN","value":"0"}]}
Your struct is not correct. Your title want dictionary, but you write an array or slice of string.
Change your FruitBasket struct from this:
type FruitBasket struct {
Name5 []string `json:"Responses"`
}
to this
type FruitBasket struct {
Name5 []map[string]interface{} `json:"Responses"`
}
map[string]interface{} is dictionary in go
here's the playground https://go.dev/play/p/xRSDGdZYfRN
I'm new in Go. I have json like this:
{
"3415": {
"age": 25,
"name": "Tommy"
},
"3414": {
"age": 21,
"name": "Billy"
}
}
I want to unmarshall it to struct:
type People struct {
Id map[string]PeopleDetails
}
type PeopleDetails struct {
Age int `json:"age"`
Name string `json:"name"`
}
But while I run it, I see that struct return nil value.
I did read some tutorials, but most of them have predefined keys, as You see here "id" e.g. 3415 is different for every new json.
When you have to deal with a "dynamic" json key, the answer is use a map of struct.
You can use the following code:
package main
import (
"encoding/json"
"fmt"
)
// Use the struct pointed by #Adirio
type People map[string]PeopleDetails
type PeopleDetails struct {
Age int `json:"age"`
Name string `json:"name"`
}
var data string = `{"3415":{"age":25,"name":"Tommy"},"3414":{"age":21,"name":"Billy"}}`
func main() {
var p People
if err := json.Unmarshal([]byte(data), &p); err != nil {
fmt.Println(err)
}
fmt.Println(p)
}
GoPlayground: https://play.golang.org/p/kVzNV56NcTd
Try with these types instead:
type People map[string]PeopleDetails
type PeopleDetails struct {
Age int `json:"age"`
Name string `json:"name"`
}
I have a struct like so:
type my_struct struct {
First string `json:"first"`
Second string `json:"second"`
Number int `json:"number"`
}
When I marshal that into JSON, it outputs very simple JSON as you'd expect:
var output_json []byte
output_json, _ = json.Marshal(output)
fmt.Println(string(output_json))
Result:
{"first":"my_string","second":"another_string","number":2}
All fine so far!
What I'd like to do, before marshalling that struct into JSON, is nest it inside another struct. The resulting output would be JSON that looks like this:
{
"fields": {
"first": "my_string",
"number": 2,
"second": "another_string"
},
"meta": "data"
}
How can I do that?
I think you could statically declare another struct to use:
type WrappedOutput struct {
fields my_struct
meta string
}
Then you could embed your struct before marshalling
o := WrappedOutput{fields: output}
Brand new to go so not sure if this is the easiest way to do it
The clean way to do this would be to declare 2 structs (I've done it globally below) and nest My_struct inside the higher level struct.
Then you can initialize the higher level struct before Mashalling it:
package main
import (
"encoding/json"
"fmt"
)
type My_struct struct {
First string `json:"first"`
Second string `json:"second"`
Number int `json:"number"`
}
type Big_struct struct {
Fields My_struct
Meta string
}
func main() {
output := Big_struct{
Fields: My_struct{
First: "my_string",
Second: "another_string",
Number: 2,
},
Meta: "data",
}
output_json, err := json.Marshal(output)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(output_json))
}
if you don't want Big_struct you can declare an anonymous struct within your code as you need it and nest My_struct inside:
package main
import (
"encoding/json"
"fmt"
)
type My_struct struct {
First string `json:"first"`
Second string `json: "second"`
Number int `json:"number"`
}
func main() {
output := struct {
Fields My_struct
Meta string
}{
Fields: My_struct{
First: "my_string",
Second: "another_string",
Number: 2,
},
Meta: "data",
}
output_json, err := json.Marshal(output)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(output_json))
}
If you don't want to use a new structure, you can do:
data := my_struct{First: "first", Second: "2", Number: 123}
result, _ := json.Marshal(&map[string]interface{}{"fields":data,"meta":"data"})
fmt.Println(string(result))
it's not clean, but it does the work.
Following the Go by Example: JSON tutorial, I see how to work with a basic JSON string:
package main
import (
"encoding/json"
"fmt"
)
type Response struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}
func main() {
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := Response{}
json.Unmarshal([]byte(str), &res)
fmt.Println(res.Page)
fmt.Println(res.Fruits)
}
// the output looks good here:
// 1
// [apple peach]
I would like to add some complexity to the str data object that I am decoding.
Namely, I would like to add a key with a slice of maps as its value:
"activities": [{"name": "running"}, {"name", "swimming"}]
My script now looks like below example, however, for the life of me, I can not figure out what the correct syntax is in the Response struct in order to get at the values in activities. I know that this syntax isn't correct: Activities []string ... but can not hack my way towards a solution that captures the data I want to display.
package main
import (
"encoding/json"
"fmt"
)
type Response struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
Activities []string `json:"activities"`
}
func main() {
str := `{"page": 1, "fruits": ["apple", "peach"], "activities": [{"name": "running"}, {"name", "swimming"}]}`
res := Response{}
json.Unmarshal([]byte(str), &res)
fmt.Println(res.Page)
fmt.Println(res.Fruits)
fmt.Println(res.Activities)
}
// the script basically craps out here and returns:
// 0
// []
// []
Thanks for any help!
Use []map[string]string:
type Response struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
Activities []map[string]string `json:"activities"`
}
playground example
Always check and handle errors.
The example JSON has a syntax error which is corrected in the playground example.
I know this is an old one, but i've recently written utility for generating exact go type from json input and in similar case you could give it a spin: https://github.com/m-zajac/json2go
For this particular example it generates from json:
{"page": 1, "fruits": ["apple", "peach"], "activities": [{"name": "running"}, {"name": "swimming"}]}
go type:
type Object struct {
Activities []struct {
Name string `json:"name"`
} `json:"activities"`
Fruits []string `json:"fruits"`
Page int `json:"page"`
}
I am trying to use the Marshal function to create JSON from a Go struct. The JSON created does not contain the Person struct.
What am I missing?
http://play.golang.org/p/ASVYwDM7Fz
type Person struct {
fn string
ln string
}
type ColorGroup struct {
ID int
Name string
Colors []string
P Person
}
per := Person{
fn: "John",
ln: "Doe",
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
P: per,
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write(b)
The output generated is as follows:
{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"],"P":{}}
I don't see Person in the output.
http://golang.org/pkg/encoding/json/#Marshal
You are missing two things.
Only Public fields can be Marshaled to json.
The name written to json is the name of the fieldd. In this case P for the field Person.
Notice that I changed the Fields name to be capital for the Person struct and that I added
a tag json on the ColorGroup Struct to indicate that I want that field to be serialized with another name. Is common to tag most of the fields and change the name to lowercase to be in sync with javascript's style.
http://play.golang.org/p/HQQ8r8iV7l
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
type Person struct {
Fn string
Ln string
}
type ColorGroup struct {
ID int
Name string
Colors []string
P Person `json:"Person"`
}
per := Person{Fn: "John",
Ln: "Doe",
}
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
P: per,
}
b, err := json.Marshal(group)
if err != nil {
fmt.Println("error:", err)
}
os.Stdout.Write(b)
}
Will output
{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"],"Person":{"Fn":"John","Ln":"Doe"}}