Golang模板数据库RestApi实现指南

Golang模板数据库RestApi实现指南 有没有人知道如何连接后端和前端的例子?

我知道我需要使用以下方式发送数据:

template.ExecuteTemplate(w, "index/html, data)

但是我使用MongoDB创建了我的API,我不知道如何正确操作 😞

我只是想将那个JSON发送到前端,例如我尝试了一些函数:

r , err := htpp.Get("localhost:3000/users")

if err != nil { 
            panic (err)
          }

defer r.Body.Close()

body, err := io.ReadAll(r.Body)

if err != nil { 
            panic (err)
          }

var users [ ]models.User = make([ ]models.User, 0)

json.Unmarshal(body, &users)
       
template.ExecuteTemplate(w, "index/html, users)

fmt.Println(string(body)) //这里我有正确的数据
fmt.Println(users) //这里我没有数据

更多关于Golang模板数据库RestApi实现指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复
  • 检查 json.Unmarshal 返回的错误。
  • 您的 models.User 结构体定义可能与 JSON 请求体的结构不匹配。
func main() {
    fmt.Println("hello world")
}

更多关于Golang模板数据库RestApi实现指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已经成功解决了这个问题,原因其实挺蠢的哈哈。我的结构体定义有些错误,而且在处理Unmarshal错误时,我发现我获取到的是一个数组,但保存的方式不对。非常感谢你,兄弟!

这是一个典型的Go模板与API数据集成问题。你的代码有几个关键问题需要解决:

主要问题分析

  1. HTTP客户端使用不当:你在后端服务中又发起了HTTP请求到自己
  2. JSON解析问题users 数组为空是因为解析失败
  3. 模板路径错误"index/html" 应该是模板文件路径

正确的实现方案

方案1:直接使用数据库数据(推荐)

// 直接从MongoDB获取数据,无需HTTP请求
func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
    // 连接MongoDB
    client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer client.Disconnect(context.TODO())

    // 获取数据
    collection := client.Database("yourdb").Collection("users")
    cursor, err := collection.Find(context.TODO(), bson.M{})
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer cursor.Close(context.TODO())

    // 解析数据
    var users []models.User
    if err = cursor.All(context.TODO(), &users); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 渲染模板
    tmpl, err := template.ParseFiles("templates/index.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    tmpl.Execute(w, users)
}

方案2:如果你确实需要调用自己的API

func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
    // 调用API端点
    resp, err := http.Get("http://localhost:3000/api/users")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    // 读取响应
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 正确解析JSON - 添加错误检查
    var users []models.User
    if err := json.Unmarshal(body, &users); err != nil {
        // 调试输出
        fmt.Printf("JSON解析错误: %v\n", err)
        fmt.Printf("原始响应: %s\n", string(body))
        http.Error(w, "数据解析失败", http.StatusInternalServerError)
        return
    }

    // 解析模板
    tmpl, err := template.ParseFiles("templates/index.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 执行模板
    if err := tmpl.Execute(w, users); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

方案3:完整的REST API + 前端模板示例

API 端点 (api.go):

// api/users.go
func GetUsersAPI(w http.ResponseWriter, r *http.Request) {
    // 从MongoDB获取数据
    users := getUsersFromMongoDB()
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(users)
}

// handlers/template.go
func RenderUsersPage(w http.ResponseWriter, r *http.Request) {
    // 直接获取数据,不通过HTTP调用
    users := getUsersFromMongoDB()
    
    // 使用正确的模板路径
    tmpl := template.Must(template.ParseFiles(
        "templates/layout.html",
        "templates/header.html",
        "templates/index.html",
    ))
    
    // 传递数据到模板
    data := map[string]interface{}{
        "Users": users,
        "Title": "用户列表",
    }
    
    tmpl.ExecuteTemplate(w, "layout", data)
}

模板文件 (templates/index.html):

{{define "content"}}
<h1>{{.Title}}</h1>
<table>
    <tr>
        <th>ID</th>
        <th>姓名</th>
        <th>邮箱</th>
    </tr>
    {{range .Users}}
    <tr>
        <td>{{.ID}}</td>
        <td>{{.Name}}</td>
        <td>{{.Email}}</td>
    </tr>
    {{end}}
</table>
{{end}}

路由设置

func main() {
    mux := http.NewServeMux()
    
    // API端点
    mux.HandleFunc("/api/users", GetUsersAPI)
    
    // 页面渲染
    mux.HandleFunc("/users", RenderUsersPage)
    
    http.ListenAndServe(":3000", mux)
}

调试建议

在你的代码中添加调试信息:

// 检查JSON结构
fmt.Printf("响应状态: %d\n", resp.StatusCode)
fmt.Printf("响应体: %s\n", string(body))

// 检查模型结构
fmt.Printf("User模型: %+v\n", models.User{})

// 尝试不同的解析方式
var result map[string]interface{}
json.Unmarshal(body, &result)
fmt.Printf("解析为map: %v\n", result)

你的主要问题是尝试从后端调用自己的API,这造成了不必要的复杂性。直接使用数据库数据或确保API返回正确的JSON结构即可解决问题。

回到顶部