(1). BsyErp\Contract\main.go:
package main
import (
"Contract.bsybx.com/App/Lib"
"Contract.bsybx.com/App/Services"
"Contract.bsybx.com/Init"
)
func main () {
router := gin.Default()
v1 := router.Group("/v1")
{
// 获取book列表
v1.Handle(Init.HTTP_METHOD_GET, "/books", Lib.RegisterHandler(
Services.CreateBookListRequest(),
Services.BookListEndPoint(&Services.BookService{}),
Services.CreateBookListResponse(),
))
// 获取book详情
v1.Handle(Init.HTTP_METHOD_GET, "/book/:id", Lib.RegisterHandler(
Services.CreateBookDetailRequest(),
Services.BookDetailEndPoint(&Services.BookService{}),
Services.CreateBookDetailResponse(),
))
}
router.Run(Init.SERVER_ADDRESS)
}
(2). bookModel(BsyErp\Contract\Models\Books.go):
package Models
// 单实体
type Books struct{
BookID int `gorm:"column:book_id;AUTO_INCREMENT;PRIMARY_KEY"`
BookName string `gorm:"column:book_name;type:varchar(50)"`
BookIntr string `gorm:"column:book_intr;type:text"`
BookPrice float64 `gorm:"column:book_price;type:decimal"`
BookKind int `gorm:"column:book_kind;type:int"`
}
// 列表
type BooksList []*Books
注:
①. 属性名有规范,字段名就不一定有规范.
(4). BsyErp\Contract\App\Services\BookEndpoint.go:
package Services
import (
"Contract.bsybx.com/App/Lib"
"Contract.bsybx.com/Models"
"context"
)
// v1/books?page=1&size=1
type BookListRequest struct { // 请求参数
Page int `form:"page"`
Size int `form:"size"`
}
type BookListResponse struct { // 响应参数
Result *Models.BooksList `json:"ResultData"` // 返回一个切片
}
// v1/book/12
type BookDetailRequest struct {
// max可以做预估判断
BookID int `uri:"id" binding:"required,gt=0,max=1000000"`
}
type BookDetailResponse struct {
Result *Models.Books `json:"ResultData"` // 返回一个struct
}
func BookListEndPoint(book *BookService) Lib.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(*BookListRequest)
return &BookListResponse{Result:book.BookList(req)}, nil
}
}
func BookDetailEndPoint(book *BookService) Lib.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(*BookDetailRequest)
return &BookDetailResponse{Result:book.BookDetail(req)}, nil
}
}
注:
①. 单从上面两个EndPoint方法来看,是冗余的,有优化空间.但是加上缓存后,业务逻辑是不一样的.
(5). BsyErp\Contract\App\Services\BookService.go:
package book
import (
"api.employee.com/Init"
"api.employee.com/Models"
)
type BookService struct {
}
// 这是上次struct的方法(类似一个类的方法),在通用模型中是识别不了类方法的.
// 通用模型中的业务最终函数,是一个函数,并不是某个具体的struct或struct具体的方法,否则又耦合了.
func(this *BookService) getList(req *BookListRequest) *Models.AdminLoges {
// 如果这里不写&,在下面Find那里传&books
books := &Models.AdminLoges{}
// 请求多少条,是从req参数中获取的size,至于size怎么去取,与这个类没有任何关系,代码就结耦了
Init.GetDB().Limit(req.Size).Order("id desc").Find(books)
return books
}
func(this *BookService) getDetail(req *BookDetailRequest) *Models.AdminLogs {
book := &Models.AdminLogs{}
Init.GetDB().Find(book, req.Id)
return book
}
(6). BsyErp\Contract\App\Services\BookTransport.go:
package Services
import (
"Contract.bsybx.com/App/Lib"
)
func CreateBookListRequest() Lib.EncodeRequestFunc {
return func(context *gin.Context) (i interface{}, e error) {
req := &BookListRequest{}
// 和框架有关系了,获取一个get参数,并且绑定到BookListRequest上,会去寻找这个BookListRequest struct中是否有size。如果有绑定,否则出错。
err := context.BindQuery(req)
fmt.Println(req)
if err != nil{
return nil, err
}
return req, nil
}
}
func CreateBookListResponse() Lib.DecodeResponseFunc {
return func(context *gin.Context, i interface{}) error {
res := i.(*BookListResponse) // 取出BookListResponse,后再断言
context.JSON(200, res)
return nil
}
}
func CreateBookDetailRequest() Lib.EncodeRequestFunc {
return func(context *gin.Context) (interface{}, error) {
req := &BookDetailRequest{}
// 优化把err合并为一句
if err := context.ShouldBindUri(req); err != nil {
return nil, err
}
return req, nil
}
}
func CreateBookDetailResponse() Lib.DecodeResponseFunc {
return func(context *gin.Context, i interface{}) error {
res := i.(*BookDetailResponse)
context.JSON(200, res)
return nil
}
}
注:
①. 两个Response都是差不多逻辑,可以优化为:
func CreateBookResponse() Lib.DecodeResponseFunc {
return func(context *gin.Context, res interface{}) error {
context.JSON(200, res)
return nil
}
}
(7). 请求访问:
①. 列表:
GET http://localhost/v1/books?page=1&size=1
②. 详情:
GET http://localhost/v1/book/200