3

更方便的在微信公众号阅读文章可以关注公众号:海生的go花园
image.png

在上一节文章里 go微服务框架Kratos (连载二) :定义api接口以及实现 我们学会了 定义以及实现kratos的api方法

本章节,我们学习如何定义一个 创建一个自己的 restful接口 。

一、创建user的restful接口 proto 文件

在官方文档 https://go-kratos.dev/docs/co... 里面,介绍了,如何创建一个 api 。
我们这里生成一个user.proto,使用:

//生成 proto文件模版
kratos proto add api/helloworld/v1/user.proto

我们发现在 api/helloworld/v1文件夹里,生成了一份 user.proto文件
image.png
生成了user的增删改查,接口

CreateUser() 表示增
DeleteUser() 表示删
UpdateUser() 表示修改
GetUser() 查询一条
ListUser() 查询多条

二、修改proto文件,定义restful路由

我们先引入proto的http的类库

import "google/api/annotations.proto";

在user.proto文件,引入上面的库
image.png

2.1 修改 CreateUser()的http api 路由

我们把源码的

 rpc CreateUser (CreateUserRequest) returns (CreateUserReply);

修改如下:

rpc CreateUser (CreateUserRequest) returns (CreateUserReply){
    option (google.api.http) = {
      post: "/user",
      body: "*",
    };
  };

2.2 修改 DeleteUser()的http api 路由

我们把源码的

 rpc DeleteUser (DeleteUserRequest) returns (DeleteUserReply);

修改如下:

  rpc DeleteUser (DeleteUserRequest) returns (DeleteUserReply){
    option (google.api.http) = {
      delete: "/user/{id}",
    };
  };

因为这里接受了 id 参数,所以我们需要定义下DeleteUserRequest
把源码的

message DeleteUserRequest {}

修改如下:

message DeleteUserRequest {
  int64 id = 1;
}

2.3 修改 UpdateUser()的http api 路由

我们把源码的

 rpc UpdateUser (UpdateUserRequest) returns (UpdateUserReply);

修改如下:

  rpc UpdateUser (UpdateUserRequest) returns (UpdateUserReply){
    option (google.api.http) = {
      put: "/user/{id}",
      body: "*",
    };
  };

因为这里接受了 id 参数,所以我们需要定义下UpdateUserRequest
把源码的

message UpdateUserRequest {}

修改如下:

message UpdateUserRequest {
  int64 id = 1;
}

2.4 修改 GetUser()的http api 路由

我们把源码的

  rpc GetUser (GetUserRequest) returns (GetUserReply)

修改如下:

  rpc GetUser (GetUserRequest) returns (GetUserReply){
    option (google.api.http) = {
      get: "/user/{id}",
      body: "*",
    };
  };

因为这里接受了 id 参数,所以我们需要定义下GetUserRequest
把源码的

message GetUserRequest {}

修改如下:

message GetUserRequest {
  int64 id = 1;
}

message GetUserReply {
  int64 id = 1;
}

2.5 修改 ListUser()的http api 路由

我们把源码的

  rpc ListUser (ListUserRequest) returns (ListUserReply)

修改如下:

 rpc ListUser (ListUserRequest) returns (ListUserReply){
    option (google.api.http) = {
      get: "/users",
    };
  };

三、执行make api,生成对应的api接口

➜ make api

我们发现在 api/helloworld/v1 目录下,生成了好几个文件如下:

user.pb.go
user_grpc.pb.go
user_http.pb.go

我们打开 user_http.pb.go 看一下api需要实现的接口

type UserHTTPServer interface {
    CreateUser(context.Context, *CreateUserRequest) (*CreateUserReply, error)
    DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserReply, error)
    GetUser(context.Context, *GetUserRequest) (*GetUserReply, error)
    ListUser(context.Context, *ListUserRequest) (*ListUserReply, error)
    UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserReply, error)
}

func RegisterUserHTTPServer(s *http.Server, srv UserHTTPServer) {
    r := s.Route("/")
    r.POST("/user", _User_CreateUser0_HTTP_Handler(srv))
    r.PUT("/user/{id}", _User_UpdateUser0_HTTP_Handler(srv))
    r.DELETE("/user/{id}", _User_DeleteUser0_HTTP_Handler(srv))
    r.GET("/user/{id}", _User_GetUser0_HTTP_Handler(srv))
    r.GET("/users", _User_ListUser0_HTTP_Handler(srv))
}

四、生成service,并注入到kratos中的http或者grpc服务中

4.1 生成service

我们使用官方自带的 proto server 工具来生成service

kratos proto server api/helloworld/v1/user.proto -t internal/service

我们发现会在 internal/service目录生成一个 user.go 文件。
image.png
工具帮我们生成了对应的方法,我们只要实现就可以了。

4.2 依赖注入UserService

我们打开internal/service/service.go文件
image.png
把原来的:

var ProviderSet = wire.NewSet(NewGreeterService)

修改成

var ProviderSet = wire.NewSet(NewGreeterService,NewUserService)

然后再执行

make generate

4.3 把UserService注入到 http服务中

我们打来internal/server/http.go文件
在NewHTTPServer()函数中,增加参数userService *service.UserService
以及函数内实现 v1.RegisterUserHTTPServer(srv, userService) 具体如下图
image.png
然后再执行

make generate

4.4 在浏览器中访问 http://localhost:8000/user/1

我们重新编译一下:

go run ./cmd/helloworld  -conf  configs/config.yaml

然后在浏览器中访问 http://localhost:8000/user/1
结果如下:
image.png
可以访问了,只是结果为一个空的默认的返回值结构体。

五、实现 UserService 接口中的方法

5.1 实现 GetUser接口

我们把

func (s *UserService) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserReply, error) {
    return &pb.GetUserReply{}, nil
}

修改成如下,增加了一个返回的id,把请求的id返回出来

func (s *UserService) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserReply, error) {
    return &pb.GetUserReply{Id: req.Id}, nil
}

此时我们再重新编译一下,浏览器访问如下:
image.png
id被我们接受到了。此时我们的第一个接口实现也就完成了。

更方便的在微信公众号阅读文章可以关注公众号:海生的go花园
image.png


海生
104 声望32 粉丝

与黑夜里,追求那一抹萤火。