【Go Web开发】查询数据列表

2022-02-16  本文已影响0人  Go语言由浅入深

接着上一篇文章的内容,实现GET /v1/movies接口返回真实数据。

现在,我们先忽略客户端提供的任何查询字符串值,并返回按电影ID排序的所有电影记录。这将为我们后面功能开发打下基础,可以在此基础上开发过滤、排序和分页等特定功能。

本节的目标是让接口返回一个包含所有电影列表的JSON响应,类似如下:

{
    "movies":
    [
        {
            "id": 1,
            "title": "Moana",
            "year": 2015,
            "runtime": "107 mins",
            "genres":
            [
                "animation",
                "adventure"
            ],
            "version": 1
        },
        {
            "id": 2,
            "title": "Black Panther",
            "year": 2018,
            "runtime": "134 mins",
            "genres":
            [
                "sci-fi",
                "action",
                "adventure"
            ],
            "version": 2
        }
        ...etc
    ]
}

更新应用程序

为了从PostgreSQL数据库中查询这些数据,让我们在数据库模型中创建一个新的GetAll()方法,它执行以下SQL查询:

SELECT id, created_at, title, year, runtime, genres, version 
FROM movies
ORDER BY id

因为我们期望这个SQL查询返回多条记录,所以需要使用Go的QueryContext()方法来运行它。如下所示:

File:internal/data/movies.go


// GetAll() 返回movies切片
func (m MovieModel)GetAll(title string, genres []string, filters Filters) ([]*Movie, error)  {
    query := `
        SELECT id, create_at, title, year, runtime, genres, version
        FROM movies
        ORDER BY id`
    //创建3s超时上下文实例
    ctx, cancel := context.WithTimeout(context.Background(), 3 * time.Second)
    defer cancel()
    //使用QueryContext()来执行查询
    rows, err := m.DB.QueryContext(ctx, query)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

        //初始化切片,用户存储查询结果
    movies := []*Movie{}
    for rows.Next(){
        var movie Movie
        err := rows.Scan(
            &movie.ID,
            &movie.CreateAt,
            &movie.Title,
            &movie.Year,
            &movie.Runtime,
            pq.Array(&movie.Genres),
            &movie.Version,
            )
        if err != nil {
            return nil, err
        }
        movies = append(movies, &movie)
    }
        //rows.Next()循环结束,调rows.Err()查看是否迭代过程中发送错误
    if err = rows.Err(); err != nil {
        return nil, err
    }
    return movies, nil
}

接下来,我们需要调整listMoviesHandler,以便它调用新的GetAll()方法来检索电影数据,然后将该数据作为JSON响应写入。

更新接口处理程序如下所示:

File:cmd/api/movies.go


package main

...

func (app *application) listMoviesHandler(w http.ResponseWriter, r *http.Request) {
    var input struct {
        Title  string
        Genres []string
        data.Filters
    }

    v := validator.New()
    qs := r.URL.Query()

    input.Title = app.readString(qs, "title", "")
    input.Genres = app.readCSV(qs, "genres", []string{})

    input.Filters.Page = app.readInt(qs, "page", 1, v)
    input.Filters.PageSize = app.readInt(qs, "page_size", 20, v)

    input.Filters.Sort = app.readString(qs, "sort", "id")
    //检查校验是否通过
    if data.ValidateFilters(v, input.Filters); !v.Valid(){
        app.failedValidationResponse(w, r, v.Errors)
        return
    }

    //调用 GetAll()方法从数据库中查询movie记录
    movies, err := app.models.Movies.GetAll(input.Title, input.Genres, input.Filters)
    if err != nil {
        app.serverErrorResponse(w, r, err)
        return
    }
    err = app.writeJSON(w, http.StatusOK, envelope{"movies": movies}, nil)
    if err != nil {
        app.serverErrorResponse(w, r, err)
    }
}

现在我们应该准备好试一下效果了。重启服务,然后发送GET /v1/movies请求,你将看到GetAll()函数返回的movie列表。如下所示:

$  curl localhost:4000/v1/movies

返回结果如下:

{
        "movies": [
                {
                        "id": 1,
                        "title": "Moana",
                        "year": 2016,
                        "runtime": "107 mins",
                        "genres": [
                                "animation",
                                "adventure"
                        ],
                        "Version": 1
                },
                {
                        "id": 2,
                        "title": "Black Panther",
                        "year": 2018,
                        "runtime": "134 mins",
                        "genres": [
                                "sci-fi",
                                "action",
                                "adventure"
                        ],
                        "Version": 2
                },
                {
                        "id": 4,
                        "title": "The Breakfast Club",
                        "year": 1985,
                        "runtime": "97 mins",
                        "genres": [
                                "comedy",
                                "drama"
                        ],
                        "Version": 15
                }
        ]
}
上一篇下一篇

猜你喜欢

热点阅读