Golang中使用Gin框架实现REST API的POST和GET请求

Golang中使用Gin框架实现REST API的POST和GET请求 在使用Golang Gin REST API时,我创建了标题、正文、日期、标题数组和内容数组字段,发送到Postman并保存到数据库。POST操作成功运行,但当我接收数据时,遇到了这样的错误:“error”: “failed to import jobs”。GET请求不工作,但POST请求工作正常,相关代码如下:

main.go:

type Job struct {
    ID       int       `db:"id" json:"id"`
    Title    string    `db:"title" json:"title"`
    Body     string    `db:"body" json:"body"`
    Date     time.Time `db:"date" json:"date"`
    Titles   [4]string `db:"titles" json:"titles"`
    Contents [4]string `db:"contents" json:"contents"`
}

func main() {
r.POST("/job", func(c *gin.Context) {
    var job Job
    if err := c.ShouldBindJSON(&job); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // insert job into database
    query := "INSERT INTO table (title, body,  titles, contents ,date) VALUES ($1, $2, $3,  $4, $5) RETURNING id"
    var id int
    err := db.QueryRow(query, job.Title, job.Body, pq.Array(job.Titles), pq.Array(job.Contents), time.Now()).Scan(&id)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create job"})
        return
    }

    job.ID = id

    c.JSON(http.StatusOK, job)
})

r.GET("/jobs", func(c *gin.Context) {
    // retrieve all jobs from database
    rows, err := db.Query("SELECT * FROM table")
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve jobs"})
        return
    }
    defer rows.Close()

    // iterate over rows and store in slice of Jobs
    jobs := []Job{}
    for rows.Next() {
        var job Job
        err := rows.Scan(&job.ID, &job.Title, &job.Body, &job.Date, &job.Titles, &job.Contents)
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve jobs"})
            return
        }
        jobs = append(jobs, job)
    }

    c.JSON(http.StatusOK, jobs)
})

更多关于Golang中使用Gin框架实现REST API的POST和GET请求的实战教程也可以访问 https://www.itying.com/category-94-b0.html

10 回复

它运行了,但值是空的

更多关于Golang中使用Gin框架实现REST API的POST和GET请求的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你能澄清一下哪些值是空值吗?

当我获取数据时,值没有出现,页面空白但状态码为200,并且页面卡住了。

Coding_Yaz:

rows, err := db.Query("SELECT * FROM table")

你应该将 err 记录到某个地方,以便了解根本原因。

抱歉,我刚刚在调试中看到了这个。

2023/03/21 17:25:21 从数据库扫描作业时出错:sql: 扫描列索引 3 时出错,列名 “titles”:不支持的扫描,将 driver.Value 类型 string 存储到类型 *time.Time 中

这个错误似乎表明您正在将 titles 列扫描到 &job.Date 字段中。我建议您不要使用 select * from ...,而是显式地选择列,这样在未来添加/删除/重新排序列时,就不太可能出现此类错误。

func main() {
    fmt.Println("hello world")
}

我的意思是,你的 select 语句返回 rows 和一个 err。那个 err 很可能包含解释你的 SQL 语句为何失败的信息。当你检查 if err != nil 时,你应该记录 err 本身,以便了解问题所在:

rows, err := db.Query("SELECT * FROM table")
if err != nil {
    c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve jobs"})
    // 在这里为你的 API 返回一个通用的 "failed to retrieve jobs" 消息
    // 是可以的,但你应该在此处的某个地方记录 `err` 本身:
    //
    // TODO: import "log"
    log.Print("error getting jobs: %v", err)
    return
}

抱歉,@Coding_Yaz,我很难理解你的意思:

我建议的 log.Print 改动并不是为了修复问题,只是为了获取更多关于 SQL 语句失败原因的信息。你是看到了一个错误并做了修改来解决它,还是说在添加了 log.Print 调用之后,你现在没有收到错误,但网站却以某种方式卡住了?当你运行 Go 程序时,控制台有任何输出吗?

blank page but 200 freezes

我不太确定你这里的意思:你是得到了一个空白页面和/或一个 200 响应,还是页面“冻结”了?我认为“冻结”意味着你根本没有得到任何响应;是这种情况吗?或者你是否在运行一些客户端 JavaScript,它本应该对响应做些处理,但现在却卡住了?

错误部分出现此错误:“failed to retrieve jobs”

jobs := []Job{}
for rows.Next() {
var job Job
err := rows.Scan(&job.ID, &job.Title, &job.Body, &job.Date, &job.Titles, &job.Contents)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve jobs"})
return
}
jobs = append(jobs, job)

// Debugging statements
fmt.Printf("Retrieved job with ID %d\n", job.ID)
fmt.Printf("Title: %s\n", job.Title)
fmt.Printf("Body: %s\n", job.Body)
fmt.Printf("Date: %s\n", job.Date)
fmt.Printf("Titles: %v\n", job.Titles)
fmt.Printf("Contents: %v\n", job.Contents)
}

从代码来看,GET请求失败是因为数据库查询返回的数组字段与Go结构体中的数组类型不匹配。PostgreSQL的数组字段需要使用pq.Array()进行扫描。以下是修正后的GET处理函数:

r.GET("/jobs", func(c *gin.Context) {
    rows, err := db.Query("SELECT id, title, body, date, titles, contents FROM table")
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to retrieve jobs"})
        return
    }
    defer rows.Close()

    jobs := []Job{}
    for rows.Next() {
        var job Job
        err := rows.Scan(
            &job.ID,
            &job.Title,
            &job.Body,
            &job.Date,
            pq.Array(&job.Titles),
            pq.Array(&job.Contents),
        )
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to import jobs"})
            return
        }
        jobs = append(jobs, job)
    }

    if err = rows.Err(); err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to process jobs"})
        return
    }

    c.JSON(http.StatusOK, jobs)
})

同时确保导入正确的包:

import (
    "github.com/lib/pq"
)

对于POST请求,也需要检查数据库表结构是否与结构体字段匹配。确保数据库中的titlescontents字段类型为文本数组(例如text[])。

回到顶部