easy_note此示例代码调用逻辑 | 豆包MarsCode AI刷题

185 阅读3分钟

hz生成代码

hertz_gen_model:
    hz model --idl=idl/api.thrift --mod=MyNote2 --model_dir=hertz_gen

hertz_gen_client:
    hz client --idl=idl/api.thrift --base_domain=http://127.0.0.1:8080 --client_dir=api_request --mod=MyNote2 --model_dir=hertz_gen

hz model 只有model侧在hz_gen

hz client 只有cli侧在api_request

hz_new生成其他代码,直接使用不生成model侧(handler,router,main)

hertz_new_api:
    hz new --idl=../../idl/api.thrift --service=api --router_dir=hertz_router --handler_dir=hertz_handler -f -use=MyNote2/hertz_gen

kitex代码生成

先生成基本的rpc代码在kitex_gen

kitex_gen_user:
    kitex  -module MyNote2 idl/user.thrift # execute in the project root directory

kitex_gen_note:
    kitex  -module MyNote2 idl/note.thrift # execute in the project root directory

再生成server端,包括handler函数处理的方式和main函数

kitex_gen_server:
    kitex --thrift-plugin validator -module MyNote2 -service user -use MyNote2/kitex_gen ../../idl/user.thrift # execute in cmd/user

从接收到请求的函数调用是什么

路由注册在哪里

  • 在hz router中的api,分组自动注册,不让编辑

  • 同目录下还有middlerware文件,不知道干嘛的

和hz router同级别的还有handler,main,是不是这两个进行请求的?

  • hz handler下的确有api_service,列举了各种函数处理

    • 应该是可以自己修改的
  • 以hz router handler CreateUser为例

  • 没找到它的调用,那么是不是函数里面进行的传递

  • 有个SendResponse函数,无论如何都会调用*app.RequestContext.JSON函数,成功或者失败都有信息发送

SendResponse(c, errno.ConvertErr(err), nil)
SendResponse(c, errno.Success, nil)
  • app.RequestContext.JSON函数在库herts context.go中,调用RequestContext.Render渲染函数
func (ctx *RequestContext) JSON(code int, obj interface{}) {
    ctx.Render(code, render.JSONRender{Data: obj})
}
  • ctx.Render函数是用来渲染的,首先设置状态码

    • 这里有一个检查,如果根据给定的状态码(code),响应主体不被允许(例如,204 No Content304 Not Modified 状态码通常不包含响应主体),则调用 r.WriteContentType 来写入内容类型,但不进行渲染,直接返回。
    • 然后调用 r.Render(&ctx.Response) 渲染响应数据
    • 这是结构体函数写法
// Render writes the response headers and calls render.Render to render data.
func (ctx *RequestContext) Render(code int, r render.Render) {
    ctx.SetStatusCode(code)

    if !bodyAllowedForStatus(code) {
       r.WriteContentType(&ctx.Response)
       return
    }

    if err := r.Render(&ctx.Response); err != nil {
       panic(err)
    }
}
  • 然后就不深究了,反正就是response的code和内容都写好了,但是在这里SendResponse函数只起到一个写code的作用

然后hz router handler CreateUser里面还有一个调用构建resp:hz rpc CreateUser

err = rpc.CreateUser(ctx, &demouser.CreateUserRequest{
    Username: req.Username,
    Password: req.Password,
})

1.&demouser.CreateUserRequest是什么

是一个结构体,只用来创建构造

type CreateUserRequest struct {
    Username string `thrift:"username,1" json:"username"`
    Password string `thrift:"password,2" json:"password"`
}

2.hz rpc CreateUser函数是什么

// CreateUser create user info
func CreateUser(ctx context.Context, req *demouser.CreateUserRequest) error {
    resp, err := userClient.CreateUser(ctx, req)
    if err != nil {
       return err
    }
    if resp.BaseResp.StatusCode != 0 {
       return errno.NewErrNo(resp.BaseResp.StatusCode, resp.BaseResp.StatusMessage)
    }
    return nil
}
  • 首先调用了userClient.CreateUser(ctx, req)

    • userClient是var userClient userservice.Client,

      • userservice在kitex_gen userservice下
      • 这个userClient是rpc中函数的接口
// Client is designed to provide IDL-compatible methods with call-option parameter for kitex framework.
type Client interface {
    CreateUser(ctx context.Context, req *demouser.CreateUserRequest, callOptions ...callopt.Option) (r *demouser.CreateUserResponse, err error)
    MGetUser(ctx context.Context, req *demouser.MGetUserRequest, callOptions ...callopt.Option) (r *demouser.MGetUserResponse, err error)
    CheckUser(ctx context.Context, req *demouser.CheckUserRequest, callOptions ...callopt.Option) (r *demouser.CheckUserResponse, err error)
}

然后又封装了一次叫kClient

构造resp的 resp, err := userClient.CreateUser(ctx, req)

从rpc main侧来看

svr := demonote.NewServer(new(NoteServiceImpl))

NewServer要传入rpc service:demonote.NoteService结构体

// NewServer creates a server.Server with the given handler and options.
func NewServer(handler demonote.NoteService, opts ...server.Option) server.Server {

rpc service:demonote.NoteService是一个结构体

type NoteService interface {
    CreateNote(ctx context.Context, req *CreateNoteRequest) (r *CreateNoteResponse, err error)

    DeleteNote(ctx context.Context, req *DeleteNoteRequest) (r *DeleteNoteResponse, err error)

    UpdateNote(ctx context.Context, req *UpdateNoteRequest) (r *UpdateNoteResponse, err error)

    QueryNote(ctx context.Context, req *QueryNoteRequest) (r *QueryNoteResponse, err error)

    MGetNote(ctx context.Context, req *MGetNoteRequest) (r *MGetNoteResponse, err error)
}

所以rpc handler中就是函数内容

暂时无法在飞书文档外展示此内容