Golang中如何接收数组请求并逐个返回响应
Golang中如何接收数组请求并逐个返回响应 我遇到一个需求,用户可以通过数组中的一个键传递多个值。我希望应用程序能对数组中的每个值运行验证,并相应地打印响应。
示例输入:
{
"ticket": [
"abc",
"def",
"ghi",
],
"user": "xyzasb"
}
我希望将票据 [abc, def, ghi] 作为输入变量传递给一个使用 GET 方法的第三方 API,并将收到的响应一个接一个地打印出来。
8 回复
我不太明白你的问题。你对这个要求的哪一部分有疑问?你已经实现了哪些部分,还缺少什么?
感谢Yamil,实际上需求是根据工单类型来决定是使用INC搜索还是CHG搜索,并将两种工单的响应结果一个接一个地打印出来。
我当前的实现仅接受键“ticket”的单个值并给出响应。现在我希望该键的值可以是多个数组,并为每个值返回所需的响应。
你可以使用一个映射(Map)来关联你的票据与响应。
我的意思是,获取 snowapiresp 的值并将其存储在一个映射中,例如:
m = make(map[string]*Response)
key := fmt.Sprintf(SnowInc + SnowTicket)
m[key] = nil
// 处理URL,当你获得snowapiresp时,将其存储在你的映射中
m[key] = snowapiresp
请求数据类似这样
{
"tickets": [ "INC0012345678",
"CHG0012345678",
"CHG0012345679",
"INC0012345679"
],
"IncludeDetail": true,
"mwuser": "abcd"
}
第三方 API 的 URL 根据工单类型而有所不同:如果前三个字符是 “INC”,则调用 URL = A;如果是 “CHG”,则调用 URL = B。
基于选定的 URL,我将执行 client.Get。
//Third Party SNOW API Call
var snowapiresp *http.Response
if strings.Contains(SnowTicket, "INC") {
snowapiresp, err = client.Get(fmt.Sprintf(SnowInc + SnowTicket))
if err != nil {
fmt.Println(err.Error())
}
} else {
snowapiresp, _ = client.Get(fmt.Sprintf(SnowChg + SnowTicket))
if err != nil {
fmt.Println(err.Error())
}
}
并为每个工单号打印响应。
在Golang中处理数组请求并逐个返回响应,可以通过以下方式实现:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"sync"
)
// 请求结构体
type RequestData struct {
Ticket []string `json:"ticket"`
User string `json:"user"`
}
// API响应结构体(根据实际API调整)
type APIResponse struct {
Data interface{} `json:"data"`
Success bool `json:"success"`
}
func main() {
http.HandleFunc("/process", processHandler)
http.ListenAndServe(":8080", nil)
}
func processHandler(w http.ResponseWriter, r *http.Request) {
// 解析请求体
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "读取请求体失败", http.StatusBadRequest)
return
}
var req RequestData
if err := json.Unmarshal(body, &req); err != nil {
http.Error(w, "JSON解析失败", http.StatusBadRequest)
return
}
// 验证ticket数组
if len(req.Ticket) == 0 {
http.Error(w, "ticket数组不能为空", http.StatusBadRequest)
return
}
// 设置响应头
w.Header().Set("Content-Type", "application/json")
// 使用WaitGroup等待所有goroutine完成
var wg sync.WaitGroup
responses := make([]APIResponse, len(req.Ticket))
// 为每个ticket并发调用API
for i, ticket := range req.Ticket {
wg.Add(1)
go func(idx int, tkt string) {
defer wg.Done()
// 调用第三方API
resp, err := callThirdPartyAPI(tkt)
if err != nil {
responses[idx] = APIResponse{
Data: fmt.Sprintf("调用API失败: %v", err),
Success: false,
}
return
}
responses[idx] = resp
}(i, ticket)
}
wg.Wait()
// 返回所有响应
json.NewEncoder(w).Encode(responses)
}
func callThirdPartyAPI(ticket string) (APIResponse, error) {
// 构建API URL
apiURL := fmt.Sprintf("https://api.example.com/ticket/%s", ticket)
// 发送GET请求
resp, err := http.Get(apiURL)
if err != nil {
return APIResponse{}, err
}
defer resp.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return APIResponse{}, err
}
var apiResp APIResponse
if err := json.Unmarshal(body, &apiResp); err != nil {
return APIResponse{}, err
}
return apiResp, nil
}
如果需要逐个流式返回响应(而不是等待所有完成),可以使用Server-Sent Events:
func streamHandler(w http.ResponseWriter, r *http.Request) {
// ... 解析请求部分同上 ...
// 设置SSE头
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
return
}
// 为每个ticket调用API并立即返回
for _, ticket := range req.Ticket {
resp, err := callThirdPartyAPI(ticket)
var result string
if err != nil {
result = fmt.Sprintf(`{"ticket":"%s","error":"%v"}`, ticket, err)
} else {
jsonData, _ := json.Marshal(resp)
result = fmt.Sprintf(`{"ticket":"%s","response":%s}`, ticket, string(jsonData))
}
// 发送SSE格式数据
fmt.Fprintf(w, "data: %s\n\n", result)
flusher.Flush()
}
}
对于简单的顺序处理:
func sequentialHandler(w http.ResponseWriter, r *http.Request) {
// ... 解析请求部分同上 ...
w.Header().Set("Content-Type", "application/json")
var responses []map[string]interface{}
for _, ticket := range req.Ticket {
resp, err := callThirdPartyAPI(ticket)
if err != nil {
responses = append(responses, map[string]interface{}{
"ticket": ticket,
"error": err.Error(),
"success": false,
})
} else {
responses = append(responses, map[string]interface{}{
"ticket": ticket,
"data": resp.Data,
"success": resp.Success,
})
}
}
json.NewEncoder(w).Encode(responses)
}


