App
└─ Services
├─ BookService.go 业务类(具体业务函数):
│ ①. 与架构无关,框架无关性代码.
│ ②. 不管是使用什么框架,使用grpc、go-mrico,这些代码是不变的.
│
├─ BookEndpoint.go Request和Response定义:
│ ①. 跟架构没有太大关系.
│ ②. 除了手工定义外,还可以通过proto文件自动生成(grpc).
| ③. 专门存放request和response的定义(只是定义,下面是具体的操作规则).
| a. 如请求参数定义
| b. 业务最终函数定义
| (1). 因为通用模型中的业务最终函数,是一个函数,并不是某个具体的struct或struct具体的方法.
│
└─ BookTransport.go 怎么取出参数和怎么处理响应:
①. 和架构有关系的
约定涉及到的对象一律使用指针.
(1). BsyErp\Contract\main.go:
package main
import (
. "api.employee.com/Init"
"api.employee.com/Lib"
"api.employee.com/Models"
"api.employee.com/Service/book"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
v1 := router.Group("/v1")
{
bookService := &book.BookService{}
bookListHandler := Lib.RegisterHandler(book.CreateBookListRequest(),
book.BookListEndpoint(bookService),
book.CreateBookListResponse())
v1.Handle(HTTP_METHOD_GET, "/admin/books", bookListHandler)
}
router.Run(SERVER_ADDRESS)
}
(2). bookModel(BsyErp\Contract\Models\Books.go):
package Models
// 单实体
type AdminLogs struct {
Id int `json:"id" gorm:"column:book_id;AUTO_INCREMENT;PRIMARY_KEY"`
UserId int `gorm:"column:user_id;type:int"`
Ip string `gorm:"column:ip;type:varchar(45)"`
SayMore string `gorm:"column:syamore;type:varchar(255)"`
Type int `gorm:"column:type;type:int"`
CreatedAt string `gorm:"column:created_at;type:varchar(255)"`
UpdatedAt string `gorm:"column:updated_at;type:varchar(255)"`
}
// 列表
type AdminLoges []*AdminLogs
注:
①. 属性名有规范,字段名就不一定有规范.
(4). BsyErp\Contract\App\Services\BookEndpoint.go:
package book
import (
"api.employee.com/Lib"
"api.employee.com/Models"
"github.com/gin-gonic/gin"
)
// 定义请求结构体
type BookListRequest struct {
Size int `form:"size"`
}
// 定义返回结构体
type BookListResponse struct {
Result *Models.AdminLoges
}
// 业务最终函数
// 目的是把service中的struct的方法的过程,用func来做一层包装
// 为了将最终执行的结果与框架进行结耦,确保通用模型中的RegisterHandler与框架、业务无关
func BookListEndpoint(book *BookService) Lib.Endpoint {
return func(ctx *gin.Context, request interface{}) (interface{}, error) {
req := request.(*BookListRequest)
return &BookListResponse{Result: book.getList(req)}, nil
}
}
(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
}
(6). BsyErp\Contract\App\Services\BookTransport.go:
package book
import (
"api.employee.com/Lib"
"github.com/gin-gonic/gin"
)
// 返回类型是一个函数,与框架是有关的
func CreateBookListRequest() Lib.EncodeRequestFunc {
return func(ctx *gin.Context) (i interface{}, e error) {
req := &BookListRequest{}
if err := ctx.BindQuery(req); err != nil {
return nil, err
}
return req, nil
}
}
// 返回类型也是一个函数,与框架是有关的
func CreateBookListResponse() Lib.DecodeResponseFunc {
return func(cxt *gin.Context, i interface{}) error {
res := i.(*BookListResponse) // 断言
cxt.JSON(200, res)
return nil
}
}
(7). 请求访问:
①. 列表:
GET http://localhost/v1/books?size=1