Golang中如何从一个API调用返回两个参数

Golang中如何从一个API调用返回两个参数 我正在尝试创建一个API,将SQL查询存储在SQL数据库中。它能很好地返回查询并正确获取该查询的结果。

query, page = Getquery(path)

但是,我还希望存储应该使用哪个HTML页面。因为一个页面可以重用于多个查询(相同的模板但填充不同的数据)。

结果是页面名称(users)以字符串形式返回,而结果以JSON形式返回([{usr…)

fmt.Fprintf(w, "%s %s", page, json)

users [{“usr_date”:“2020-06-01T00:00:00Z”,“usr_id”:4, 等等…

如果不使用API,这样做没有问题。因为你可以直接使用查询结果。但是,如何使用REST API来实现这一点呢?

我有三个问题。

  1. 是否最好以另一种格式返回页面和JSON?
  2. 或者,如何将返回的内容读取为两个独立的参数?
  3. 或者,是否有其他方法来指定某个查询应使用特定的HTML页面?

更多关于Golang中如何从一个API调用返回两个参数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何从一个API调用返回两个参数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang的REST API中,通常建议将多个返回值封装到单一的结构体中。以下是几种专业实现方案:

方案一:使用复合JSON响应(推荐)

type APIResponse struct {
    Page    string      `json:"page"`
    Data    interface{} `json:"data"`
    Success bool        `json:"success"`
    Message string      `json:"message,omitempty"`
}

func GetQueryHandler(w http.ResponseWriter, r *http.Request) {
    query, page := Getquery(path)
    
    // 执行查询获取数据
    var results []User
    // ... 数据库查询逻辑
    
    response := APIResponse{
        Page:    page,
        Data:    results,
        Success: true,
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

客户端调用示例:

type Response struct {
    Page    string          `json:"page"`
    Data    json.RawMessage `json:"data"`
    Success bool            `json:"success"`
}

func callAPI() {
    resp, err := http.Get("http://api.example.com/query")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    
    var apiResp Response
    json.NewDecoder(resp.Body).Decode(&apiResp)
    
    fmt.Printf("Page: %s\n", apiResp.Page)
    
    // 根据页面类型解析数据
    if apiResp.Page == "users" {
        var users []User
        json.Unmarshal(apiResp.Data, &users)
        // 使用users数据
    }
}

方案二:使用HTTP头部传递页面信息

func GetQueryHandler(w http.ResponseWriter, r *http.Request) {
    query, page := Getquery(path)
    
    // 执行查询
    var results []User
    // ... 数据库查询逻辑
    
    // 在头部设置页面信息
    w.Header().Set("X-Page-Template", page)
    w.Header().Set("Content-Type", "application/json")
    
    json.NewEncoder(w).Encode(results)
}

客户端读取:

func callAPI() {
    resp, err := http.Get("http://api.example.com/query")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    
    page := resp.Header.Get("X-Page-Template")
    fmt.Printf("Page template: %s\n", page)
    
    var data []User
    json.NewDecoder(resp.Body).Decode(&data)
}

方案三:使用多部分响应(适用于特定场景)

func GetQueryHandler(w http.ResponseWriter, r *http.Request) {
    query, page := Getquery(path)
    
    var results []User
    // ... 数据库查询逻辑
    
    writer := multipart.NewWriter(w)
    w.Header().Set("Content-Type", writer.FormDataContentType())
    
    // 第一部分:页面信息
    part, _ := writer.CreatePart(textproto.MIMEHeader{
        "Content-Type": []string{"text/plain"},
        "Content-ID":   []string{"page-info"},
    })
    part.Write([]byte(page))
    
    // 第二部分:JSON数据
    part, _ = writer.CreatePart(textproto.MIMEHeader{
        "Content-Type": []string{"application/json"},
        "Content-ID":   []string{"query-data"},
    })
    json.NewEncoder(part).Encode(results)
    
    writer.Close()
}

方案四:使用查询参数指定页面

// API端点:/query?template=users
func GetQueryHandler(w http.ResponseWriter, r *http.Request) {
    template := r.URL.Query().Get("template")
    query := GetQueryByTemplate(template)
    
    var results []User
    // ... 数据库查询逻辑
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(results)
}

针对你的问题回答:

  1. 是否最好以另一种格式返回页面和JSON?
    是的,推荐使用方案一的复合JSON格式,这是REST API的标准做法。

  2. 如何将返回的内容读取为两个独立的参数?
    使用方案一,客户端可以轻松解析出页面信息和数据:

    var response struct {
        Page string          `json:"page"`
        Data json.RawMessage `json:"data"`
    }
    
  3. 是否有其他方法来指定某个查询应使用特定的HTML页面?
    可以在数据库查询表中添加template_name字段,或者使用方案四通过查询参数指定。

最推荐方案一,因为它保持了RESTful设计原则,同时提供了清晰的接口定义和易于使用的客户端体验。

回到顶部