{
"query": {
"query_string": {
"query": "<query string>"
}
}
}
The API I'm using requires that I send my queries in this format. I've been trying to find a way to to create this using maps but I keep getting errors and haven't been able to find any solutions online.
Edit: I found a way to do it, is there a better way?
test := map[string]map[string]map[string]string {
"query": map[string]map[string]string {
"query_string": map[string]string{
"query": query,
},
},
}
In Go you can unmarshal into a variety of different structures. The most ambiguous being an interface{}
. I recommend against that though as you forgo the opportunity to have any real type safety. The other extreme is to use structs, for your example json they would look like this;
type Wrapper struct {
Query Query `json:"query"`
}
type Query struct {
QueryString QueryString `json:"query_string"`
}
type QueryString struct {
Query string `json:"query"`
}
Something in the middle, given you example json would be a map[string]map[string]map[string]
. Check out the example here if you don't know how to make use of the encoding/json
package. https://golang.org/pkg/encoding/json/#example_Unmarshal
It's pretty straight forward, if you have your input in a []byte
and then you instantiate the type you want to unmarshal it into you can just call json.Unmarhsal(jsonBytes, &ThingToUnmarshalInto)
EDIT: based on hobbs' comment it appears you're actually trying to make that json to send to the server. In which case, use the structs above. The example supplied in the other answer demonstrates everything you need. Everything is pretty much the same as I described above except you're calling json.Marshal
with an instance of what you want to be turned in to a json string, rather than taking the json string as a []byte
and passing it into unmarshal to get a struct. I mistakenly thought you were receiving that json, not trying to form it.
Here's an example on Play using both the map way and the struct way.
As you can see, the map form is less code in general and more clear if you need to send one off requests like this.
Struct form will tend to be more performant and possibly more clear if there are a lot of nested or shared types in your requests. If you end up going the struct route, you would likely want something that resembles evanmcdonnal's answer. I used anonymous structs here for brevity.
package main
import "encoding/json"
import "log"
type M map[string]interface{}
type Query struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
func main() {
b, err := json.Marshal(M{"query": M{"query_string": M{"query": "query goes here"}}})
if err != nil {
log.Fatalln(err)
}
log.Println(" As Map:", string(b))
var q Query
q.Query.QueryString.Query = "query in a struct"
b, err = json.Marshal(q)
if err != nil {
log.Fatalln(err)
}
log.Println("As Struct:", string(b))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With