This is regarded the Selenium Web driver but I think it is not quite important.
I can set the browser name
caps := selenium.Capabilities{"browserName": "firefox"}
wd, _ := selenium.NewRemote(caps, "")
But for "proxy" ie:
caps := selenium.Capabilities{"proxy": "http://1.2.3.4:999"}
wd, _ := selenium.NewRemote(caps, "")
I have to pass a JSON Proxy Object which I absolutely have no idea how to create... I searched there and there, but still could not figure... Is it kind of struct? Or map.. or what... :-(
As I've said in the comment, you can use the form
selenium.Capabilities{
"proxy": map[string]interface{}{
"httpProxy": "http://1.2.3.4:999",
// etc.
}
}
Unstructured JSON is usually (un)marshalled through map[string]interface{}, and the type selenium.Capabilities is in fact just a map[string]interface{}.
See also: JSON and Go.
Related
I retrieve JSON as GET response from and endpoint
response, _ := http.Get("https://website-returning-json-value.com")
data, _ := ioutil.ReadAll(response.Body)
w.Write(data)
It returns me a JSON value, which is OK, but it is very ugly (no indents etc.). I would like to make it pretty. I've read that there is util function like MarshalIndent which does the job, but this works for JSON object (?) and ReadAll function returns []byte, so it does not work. I read the documentation regarding encoding/json package but there's a lot of information and I got a little bit stuck/confused.
As far as I understand it should be done, I should get []byte via ReadAll function -> convert it to the JSON -> prettify it -> turn to []byte again.
There is json.Indent() for this purpose. Example using it:
src := []byte(`{"foo":"bar","x":1}`)
dst := &bytes.Buffer{}
if err := json.Indent(dst, src, "", " "); err != nil {
panic(err)
}
fmt.Println(dst.String())
Output (try it on the Go Playground):
{
"foo": "bar",
"x": 1
}
But indentation is just for human eyes, it carries the same information, and libraries don't need indented JSON.
Also see: Is there a jq wrapper for golang that can produce human readable JSON output?
I have a very simple Go webserver. It's job is to receive an inbound json payload. It then publishes the payload to one or more services that expect a byte array. The payload doesn't need to be checked. Just sent over.
In this case, it receives an inbound job and sends it to Google PubSub. It might be another service - it doesn't really matter. I'm trying to find the most efficient way to convert the object to a byte array without first decoding it.
Why? Seems a bit wasteful to decode and convert to JSON on one server, only to unmarshal it later. Plus, I don't want to maintain two identical structs in two packages.
How is it possible to convert the io.ReadCloser to a byte array so I only need to unmarshal once. I tried something like this answer but don't think that's the most efficient way either:
From io.Reader to string in Go
My http server code looks like this:
func Collect(d DbManager) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
code := 422
obj := Report{}
response := Response{}
response.Message = "Invalid request"
decoder := json.NewDecoder(r.Body)
decoder.Decode(&obj)
if obj.Device.MachineType != "" {
msg,_ := json.Marshal(obj)
if d.Publish(msg, *Topic) {
code = 200
}
response.Message = "Ok"
}
a, _ := json.Marshal(response)
w.WriteHeader(code)
w.Write(a)
return
})
}
You convert a Reader to bytes, by reading it. There's not really a more efficient way to do it.
body, err := ioutil.ReadAll(r.Body)
If you are unconditionally transferring bytes from an io.Reader to an io.Writer, you can just use io.Copy
My original problem is I want to parse URL.Values to a generic type (map[interface{}]interface{}) edit/add some values then convert it to JSON string and put it to PostgreSQL JSON column.
I tried this code to parse it but content seems to be null whereas err is false. request.URL.Query() prints a nice map object.
v := reflect.ValueOf(request.URL.Query())
i := v.Interface()
content, err := i.(map[interface{}]interface{})
// Do some operations
jsonString, _ := json.Marshal(content)
// Add to DB
Why is it null? Also am I thinking too generic?
content, err := i.(map[interface{}]interface{}), this isn't a cast, it's a type assertion. You're saying (asserting) that interface is of type map[interface{}]interface{}, it's not. It's of type map[string][]string. You get null as the value because it fails. I highly doubt error is false.
Are you thinking too generic? Of course you are. I can't think of any reason why the collections type needs to change... Append what you want to it, write it to your db. There's nothing preventing that afaik?
I don't want to specify the type of my json since they are so messy and so complicated, I just want them to load into memory and I perform the lookup when needed.
It is easy with dynamic language such as python, e.g.
data = json.loads(str)
if "foo" in data:
...
How to do the same in go?
You can unmarshal into an interface{} value to decode arbitrary JSON.
Taking the example from http://blog.golang.org/json-and-go
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
... handle error
}
You need to use a type switch to access data decoded in this way. For example:
age := f.(map[string)interface{})["Age"].(int)
Here's an example which seems easier to understand for me, I hope it works for you too:
https://gobyexample.com/json . Look for the word "arbitrary"
I have a io.Reader which I get from http.Request.Body that reads a JSON byte slice from a server.
I would like to stream this to json.NewDecoder. However I would also like to intercept the JSON before it hits json.NewDecoder and substitute certain parts of it. For example, the JSON string contains empty hashes "{}" which I would like to remove due to a bug in the server's JSON output.
I am currently achieving my goal using json.Unmarshal but not using the JSON streaming parser:
data, _ := ioutil.ReadAll(r.Body)
data = bytes.Replace(data, []byte("{}"), "", -1)
json.Unmarshal(data, [my struct])
How can I achieve the same thing as above but using json.NewDecoder so I can save the many times the above code has to parse through r.Body's data? Here's some code using a pseudo function ReplaceStream(r io.Reader, old, new []byte):
reader := ReplaceStream(r.Body, []byte("{}"), "")
dec := json.NewDecoder(reader)
dec.Decode([my struct])
I know ReplaceStream might be fairly trivial to make, but is there anything in the standard library to do this that I am unaware of?
My advice is to just treat that kind of message as a special case and avoid the extra parsing / substituting for all the other requests
data, _ := ioutil.ReadAll(r.Body)
// FIXME: overcome bug #12312 of json server
if data == `{"list": [{}]}` {
return []
}
// Normal datastruct ..