项目github地址:https://github.com/sunlongv520/go-micro-code/tree/master/gjj
如果代码读起来费劲 清先参考三层架构基础篇
Go web框架构建三层架构
go-micro中集成三层架构开发模式
D:\gocode1.14.3\gocode\gjj\src\cmd\course_http_server.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/micro/go-micro/v2/web"
"jtthink/framework/gin_"
_ "jtthink/src/lib"
"log"
)
func main() {
r:=gin.New()
gin_.BootStrap(r)
//web改成micro 就是grpc,并直接注册到etcd里面
service:=web.NewService(
web.Name("api.jtthink.com.http.course"),
web.Handler(r),
)
service.Init()
if err:= service.Run(); err != nil {
log.Println(err)
}
}
三层架构:
核心:
gin_.BootStrap(r)
D:\gocode1.14.3\gocode\gjj\framework\gin_\ServiceUtil.go
package gin_
import "github.com/gin-gonic/gin"
var HandlerMap map[string]map[string]gin.HandlerFunc
func init() {
HandlerMap=make( map[string]map[string]gin.HandlerFunc)
}
func SetHandler(methods string,path string,handler gin.HandlerFunc) {
if _,ok:=HandlerMap[path];ok{
HandlerMap[path][methods]=handler
}else{
HandlerMap[path]=make(map[string]gin.HandlerFunc)
}
HandlerMap[path][methods]=handler
}
func BootStrap(router *gin.Engine) {
for path,hmap:=range HandlerMap{
for method,handler:=range hmap{
router.Handle(method,path,handler)
}
}
}
D:\gocode1.14.3\gocode\gjj\src\lib\CourseLib.go
package lib
import (
"github.com/gin-gonic/gin"
"jtthink/framework/gin_"
"jtthink/src/Course"
"jtthink/src/service"
"log"
)
func init() {
courseService:=service.NewCourseServiceImpl()
gin_.NewBuilder().WithService(courseService).
WithMiddleware(Test_Middleware()).
WithEndpoint(Courselist_Endpoint(courseService)).
WithRequest(Courselist_Request()).
WithResponse(Course_Response()).Build("/test","GET")
}
func Test_Middleware() gin_.Middleware {
return func(next gin_.Endpoint) gin_.Endpoint {
return func(context *gin.Context, request interface{}) (response interface{}, err error) {
log.Println("abc")
return next(context,request)
}
}
}
//获取列表相关
func Courselist_Endpoint(c *service.CourseServiceImpl) gin_.Endpoint {
return func(context *gin.Context, request interface{}) (response interface{}, err error) {
rsp:=&Course.ListResponse{}
err=c.ListForTop(context,request.(*Course.ListRequest),rsp)
return rsp,err
}
}
//这个函数的作用是怎么处理请求
func Courselist_Request() gin_.EncodeRequestFunc{
return func(context *gin.Context) (i interface{}, e error) {
bReq:=&Course.ListRequest{}
err:=context.BindQuery(bReq) //使用的是query 参数
if err!=nil{
return nil,err
}
return bReq,nil
}
}
//这个函数作用是:怎么处理响应结果
func Course_Response() gin_.DecodeResponseFunc {
return func(context *gin.Context, res interface{}) error {
context.JSON(200,res)
return nil
}
}
framework
D:\gocode1.14.3\gocode\gjj\framework\gin_\ServiceBuilder.go
package gin_
type ServiceBuilder struct {
service interface{}
endPoint Endpoint
requestFunc EncodeRequestFunc
responseFunc DecodeResponseFunc
methods string
middlewares []Middleware
}
func NewBuilder() *ServiceBuilder {
return &ServiceBuilder{middlewares:make([]Middleware,0)}
}
func(this *ServiceBuilder) WithService(obj interface{}) *ServiceBuilder {
this.service=obj
return this
}
func(this *ServiceBuilder) WithMiddleware(obj Middleware) *ServiceBuilder {
this.middlewares=append(this.middlewares,obj)
return this
}
func(this *ServiceBuilder) WithEndpoint(obj Endpoint) *ServiceBuilder {
this.endPoint=obj
return this
}
func(this *ServiceBuilder) WithRequest(obj EncodeRequestFunc) *ServiceBuilder {
this.requestFunc=obj
return this
}
func(this *ServiceBuilder) WithResponse(obj DecodeResponseFunc) *ServiceBuilder {
this.responseFunc=obj
return this
}
func(this *ServiceBuilder) WithMethods(methods string) *ServiceBuilder {
this.methods=methods
return this
}
func(this *ServiceBuilder) Build(path string,methods string) *ServiceBuilder{
finalEndpoint:=this.endPoint
for _,m:=range this.middlewares{ //遍历中间件
finalEndpoint=m(finalEndpoint)
}
handler:=RegisterHandler(finalEndpoint,this.requestFunc,this.responseFunc)
SetHandler(methods,path,handler)
return this
}
D:\gocode1.14.3\gocode\gjj\framework\gin_\ServiceHelper.go
package gin_
import (
"fmt"
"github.com/gin-gonic/gin"
)
type Middleware func(next Endpoint) Endpoint
//业务最终函数原型
type Endpoint func(ctx *gin.Context,request interface{}) (response interface{}, err error)
//怎么取参数
type EncodeRequestFunc func(*gin.Context) (interface{}, error)
//怎么处理业务结果
type DecodeResponseFunc func(*gin.Context, interface{}) error
func RegisterHandler(endpoint Endpoint,encodeFunc EncodeRequestFunc, decodeFunc DecodeResponseFunc) func(context *gin.Context){
return func(ctx *gin.Context) {
defer func() {
if r:=recover();r!=nil{
ctx.JSON(500,gin.H{"error":fmt.Sprintf("fatal error:%s",r)})
return
}
}()
//参数:=怎么取参数(context)
//业务结果,error:=业务最终函数(context,参数)
//
//
//怎么处理业务结果(业务结果)
req,err:=encodeFunc(ctx) //获取参数
if err!=nil{
ctx.JSON(400,gin.H{"error":"param error:"+err.Error()})
return
}
rsp,err:=endpoint(ctx,req) //执行业务过程
if err!=nil{
ctx.JSON(400,gin.H{"error":"response error:"+err.Error()})
return
}
err=decodeFunc(ctx,rsp) //处理 业务执行 结果
if err!=nil{
ctx.JSON(500,gin.H{"error":"server error:"+err.Error()})
return
}
}
}
D:\gocode1.14.3\gocode\gjj\framework\gin_\ServiceUtil.go
package gin_
import "github.com/gin-gonic/gin"
var HandlerMap map[string]map[string]gin.HandlerFunc
func init() {
HandlerMap=make( map[string]map[string]gin.HandlerFunc)
}
func SetHandler(methods string,path string,handler gin.HandlerFunc) {
if _,ok:=HandlerMap[path];ok{
HandlerMap[path][methods]=handler
}else{
HandlerMap[path]=make(map[string]gin.HandlerFunc)
}
HandlerMap[path][methods]=handler
}
func BootStrap(router *gin.Engine) {
for path,hmap:=range HandlerMap{
for method,handler:=range hmap{
router.Handle(method,path,handler)
}
}
}