Retrieve a paginated list of words using the GET
method, providing some input parameters:
Field Name | Type | json | valid | Description |
---|---|---|---|---|
Word | string | json:"word" | length:1,100 | Fuzzy search word |
Page | int | json:"page" | min:1 | Page number, default 1 |
Size | int | json:"size" | between:1,100 | Number per page, default 10 |
Add Api
First, define a structure to store the fields of a word.
api/words/v1/words_struct.go
package v1
import "github.com/gogf/gf/v2/os/gtime"
type List struct {
Id uint `json:"id"`
Word string `json:"word"`
Definition string `json:"definition"`
ProficiencyLevel uint `json:"proficiencyLevel"`
}
In ListRes
, return a slice of List
, representing the word list, and Total
indicates the total number of all words for pagination operations at the frontend.
api/words/v1/words.go
...
type ListReq struct {
g.Meta `path:"words" method:"get" sm:"List" tags:"Word"`
Word string `json:"word" v:"length:1,100" dc:"Fuzzy search word"`
Page int `json:"page" v:"min:1" dc:"Page number, default 1"`
Size int `json:"size" v:"between:1,100" dc:"Number per page, default 10"`
}
type ListRes struct {
List []List `json:"list"`
Total uint `json:"total"`
}
Write Logic
First, define a Query
structure to be used as input for the query list, strictly implementing redefined data structures at each layer.
internal/model/words.go
...
type WordQuery struct {
Uid uint
Word string
Page int
Size int
}
internal/logic/words/words.go
...
func List(ctx context.Context, query *model.WordQuery) (list []entity.Words, total uint, err error) {
if query == nil {
query = &model.WordQuery{}
}
// Handling initial values for queries
if query.Page == 0 {
query.Page = 1
}
if query.Size == 0 {
query.Size = 15
}
// Compose the query chain
db := dao.Words.Ctx(ctx)
if query.Uid > 0 {
db = db.Where("uid", query.Uid)
}
// Fuzzy search
if len(query.Word) != 0 {
db = db.WhereLike("word", fmt.Sprintf("%%%s%%", query.Word))
}
db = db.Order("created_at desc, id desc").Page(query.Page, query.Size)
data, totalInt, err := db.AllAndCount(true)
if err != nil {
return
}
list = []entity.Words{}
_ = data.Structs(&list)
total = uint(totalInt)
return
}
The above code uses db.WhereLike("word", fmt.Sprintf("%%%s%%", query.Word))
, which means fuzzy search. It generates a word LIKE '%{word}%'
clause.
AllAndCount
is used to query the data record list and total number simultaneously, commonly used in pagination scenarios to simplify pagination query logic.
Controller Calls Logic
internal/controller/words/words_v1_list.go
package words
import (
"context"
"star/api/words/v1"
"star/internal/logic/users"
"star/internal/logic/words"
"star/internal/model"
)
func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
uid, err := users.GetUid(ctx)
if err != nil {
return nil, err
}
query := &model.WordQuery{
Uid: uid,
Word: req.Word,
Page: req.Page,
Size: req.Size,
}
wordList, total, err := words.List(ctx, query)
if err != nil {
return nil, err
}
var list []v1.List
for _, v := range wordList {
list = append(list, v1.List{
Id: v.Id,
Word: v.Word,
Definition: v.Definition,
ProficiencyLevel: model.ProficiencyLevel(v.ProficiencyLevel),
})
}
return &v1.ListRes{
List: list,
Total: total,
}, nil
}
Interface Testing
$ curl -X GET http://127.0.0.1:8000/v1/words \
-H "Authorization: eyJhbGci...5U" \
-H "Content-Type: application/json" \
{
"code": 0,
"message": "",
"data": {
"list": [
{
"id": 1,
"word": "example_update",
"definition": "A representative form or pattern.",
"proficiencyLevel": 3
}
],
"total": 1
}
}