英文:
Loop over dynamic json.RawMessage data and set it as net/http headers
问题
我正在制作一个接受HTTP POST请求并从请求体中获取所需数据的"fire and forget"微服务,然后将其请求到请求体中给定的URL。
我遇到的问题是输入数据中的标头数量是动态的,也就是说可能有一个或多个标头。它们是不确定的。
因此,我将传入的请求体解组为以下结构:
type Request struct {
Headers json.RawMessage `json:"headers"`
Method string `json:"method"`
Body json.RawMessage `json:"body"`
}
type Event struct {
Url string `json:"url"`
Request Request `json:"request"`
}
使用以下代码:
var newEvent Event
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Fprintln(w, err)
}
err2 := json.Unmarshal(reqBody, &newEvent)
if err2 != nil {
fmt.Fprintln(w, err2)
}
在创建请求时,很容易将请求体传递给它:
req, err := http.NewRequest(newEvent.Request.Method, newEvent.Url, bytes.NewBuffer(newEvent.Request.Body))
if err != nil {
panic(err)
}
但是,在设置标头时,我找不到任何巧妙的方法来直接传递json.RawMessage格式。最理想的情况是,我希望像这样做:
req.Header = http.Header{newEvent.Request.Headers}
是否有任何聪明的解决方案,或者我必须选择将标头解组为字符串,然后解析字符串并使用http.Header.Add()
逐个添加它们?
英文:
I am making a fire and forget micro-service that accepts http POST requests and gathers the needed data from the request body which it then requests to the given URL in the body.
The issue I'm having is that the numbers of headers in the input data is dynamic, meaning that there can be 1 or more headers. It differs.
I therefor read Unmarshal the incoming requestBody to the following struct:
type Request struct {
Headers json.RawMessage `json:"headers"`
Method string `json:"method"`
Body json.RawMessage `json:"body"`
}
type Event struct {
Url string `json:"url"`
Request Request `json:"request"`
}
with:
var newEvent Event
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Fprintln(w, err)
}
err2 := json.Unmarshal(reqBody, &newEvent)
if err2 != nil {
fmt.Fprintln(w, err2)
}
The body is easy to just pass on when creating the request:
req, err := http.NewRequest(newEvent.Request.Method , newEvent.Url, bytes.NewBuffer(newEvent.Request.Body))
if err != nil {
panic(err)
}
But when setting the headers I can't find any nifty way to just pass the json.RawMessage format. Optimally I would just like to do something like this:
req.Header = http.Header{newEvent.Request.Headers}
Is there any smart solution for this or do I have to opt to Unmarshalling the headers to a string and then parsing the sting and add them all with http.Header.Add()
?
答案1
得分: 1
事实上,有一个聪明的解决方案可以使用map
!如果将来有人遇到这个问题,这是我所做的:
var headerMap map[string]interface{}
json.Unmarshal([]byte(newEvent.Request.Headers), &headerMap)
for key, element := range headerMap {
headerKey := fmt.Sprintf("%s", key)
headerElement := fmt.Sprintf("%s", element)
req.Header.Add(headerKey, headerElement)
}
没有必要精确指定输入,动态的json.RawMessage
声明就可以正常工作。
英文:
As a matter of fact, there was a cleaver solution using map
! If anyone comes across this in the future here's what I did:
var headerMap map[string]interface{}
json.Unmarshal([]byte(newEvent.Request.Headers), &headerMap)
for key, element := range headerMap {
headerKey := fmt.Sprintf("%s", key)
headerElement := fmt.Sprintf("%s", element)
req.Header.Add(headerKey, headerElement)
}
There was no need to exactly specify the input, the dynamic json.RawMessage
declaration worked just fine.
答案2
得分: -1
> 是否有任何智能解决方案来处理这个问题[...]?
没有。
> [...] 或者我必须选择将头部解组为字符串,然后解析字符串并使用http.Header.Add()将它们全部添加进去?
是的。
(除非你重新设计输入并摆脱json.RawMessage。)
一般来说,在Go语言中没有捷径、聪明的技巧、魔法豆或语法糖可以避免编写一些代码。
英文:
> Is there any smart solution for this [...]
No.
> [...] or do I have to opt to Unmarshalling the headers to a string and then parsing the sting and add them all with http.Header.Add()?
Yes.
(Except you redesign your input and get rid of the json.RawMessage.)
In general there are no shortcuts, no clever hacks, magic beans or syntactic sugar in Go to avoid some code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论