[ api服务的项目流程解析[go-zero] ]


创建项目案例01的ucenter-api的服务文件夹

api服务启动时

  1. 终端输入的命令行参数
  2. 读取配置文件
  3. 获取服务
  4. 创建服务结构体(mysql, redis, config, 连接等..)
  5. 创建路由结构体
  6. 注册路由
  7. 启动服务
go run main.go

main.go

package main

import (
    "flag"
    "fmt"

    "ucenter-api/internal/config"
    "ucenter-api/internal/handler"
    "ucenter-api/internal/svc"

    "github.com/zeromicro/go-zero/core/conf"
    "github.com/zeromicro/go-zero/core/logx"
    "github.com/zeromicro/go-zero/rest"
)

var configFile = flag.String("f", "etc/conf.yaml", "the config file")

func main() {
    // 1.1终端输入的命令行参数
    flag.Parse()

    // 1.2 读取配置文件
    logx.MustSetup(logx.LogConf{Stat: false, Encoding: "plain"}) // 不打印状态
    var c config.Config
    conf.MustLoad(*configFile, &c)

    // 1.3 获取一个服务
    server := rest.MustNewServer(c.RestConf)
    defer server.Stop()

    // 1.4 创建服务结构体(mysql, redis, config, 连接等..)
    ctx := svc.NewServiceContext(c)

    // 1.5 创建路由结构体
    router := handler.NewRouters(server)

    // 1.6 注册路由
    handler.RegisterHandlers(router, ctx)

    fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
    server.Start()
}

5.创建路由结构体

  1. Routers路由结构体绑定rest.server, 与rest.middleware
    • rest.server.AddRoutes()方法添加路由
    • rest.WithMiddlewares(rest.middleware, rest.Route{Method: xx, Path: xx, Handler: funcxx})添加中间件, 与回调函数

internal\handler\routes_handler.go

package handler

import (
    "net/http"

    "github.com/zeromicro/go-zero/rest"
)

type Routers struct {
    server     *rest.Server
    middleware []rest.Middleware
}

func NewRouters(server *rest.Server) *Routers {
    return &Routers{
        server: server,
    }
}

func (r *Routers) Get(path string, handlerFunc http.HandlerFunc) {
    r.server.AddRoutes(
        rest.WithMiddlewares(
            r.middleware,
            rest.Route{
                Method:  http.MethodGet,
                Path:    path,
                Handler: handlerFunc,
            },
        ),
    )
}

func (r *Routers) Post(path string, handlerFunc http.HandlerFunc) {
    r.server.AddRoutes(
        rest.WithMiddlewares(
            r.middleware,
            rest.Route{
                Method:  http.MethodPost,
                Path:    path,
                Handler: handlerFunc,
            },
        ),
    )
}

func (r *Routers) Group() *Routers {
    return &Routers{
        server: r.server,
    }
}

6.注册路由

  1. 创建处理器结构体
    • 处理器handler绑定了Logic接口方法, 方便获取接口方法
  2. 创建组
    • 只是相当于创建了路由新的路由, 但是内部的服务还是同一个
  3. 添加路由
    • 调用路由里绑定的GET, POST方法, 添加路由

internal\handler\routes.go

// Code generated by goctl. DO NOT EDIT.
package handler

import (
    // "net/http"

    "ucenter-api/internal/svc"

    // "github.com/zeromicro/go-zero/rest"
)

// 注册路由主入口
func RegisterHandlers(r *Routers, serverCtx *svc.ServiceContext) {
    // 1.6.1 创建注册处理器结构体
    register := NewRegisterHandler(serverCtx)

    // 1.6.2 创建组
    registerGroup := r.Group()
    registerGroup.Get("/register/:name", register.Register)

    registerGroup.Post("/mobile/code", register.SendCode)

}

调用grpc启动的微服务

1.配置文件etc/conf.yaml 添加etcd服务

Name: ucenterapi-api
Host: 0.0.0.0
Port: 8888
MyGrpc:
  Etcd:
    Hosts:
    - 42.193.152.252:2379
    Key: ucenter.rpc
    Token: tkn

2.internal/config/config.go

package config

import (
    "github.com/zeromicro/go-zero/rest"
    "github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
    rest.RestConf
    MyGrpc     zrpc.RpcClientConf
    DbMysql    MysqlConf
    CacheRedis RedisConf
}

3.服务文件internal/svc/servicecontext.go - 添加远程服务

package svc

import (
    "grpc-common/ucenter/uc_client"
    "ucenter-api/internal/config"

    "github.com/zeromicro/go-zero/zrpc"
)

type ServiceContext struct {
    Config        config.Config
    UCRegisterRpc uc_client.Register
}

func NewServiceContext(c config.Config) *ServiceContext {
    return &ServiceContext{
        Config:        c,
        UCRegisterRpc: uc_client.NewRegister(zrpc.MustNewClient(c.MyGrpc)),
    }
}

4.在接口中使用远程调用 - l.svcCtx.UCRegisterRpc.RegisterByPhone

package logic

import (
    "context"
    "time"

    "grpc-common/ucenter/types/register"
    "ucenter-api/internal/svc"
    "ucenter-api/internal/types"

    "github.com/zeromicro/go-zero/core/logx"
)

type RegisterLogic struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
    return &RegisterLogic{
        Logger: logx.WithContext(ctx),
        ctx:    ctx,
        svcCtx: svcCtx,
    }
}

func (l *RegisterLogic) Registerapi(req *types.Request) (resp *types.Response, err error) {
    // todo: add your logic here and delete this line
    ctx, canelFunc := context.WithTimeout(context.Background(), 5*time.Second)
    defer canelFunc()
    _, err = l.svcCtx.UCRegisterRpc.RegisterByPhone(ctx, &register.RegReq{})
    if err != nil {
        return
    }
    resp = new(types.Response)
    resp.Message = "欢迎"
    return
}