Go 语言微服务框架 Kratos 开发 HTTP API

开发 前端
本文我们介绍使用 kratos 微服务框架,怎么创建 HTTP API,介绍了怎么通过 kratos 脚手架创建项目和生成 proto 文件。Kratos 微服务框架使用 DDD 和 DI 的代码架构,我们介绍 kratos 模板生成的代码目录的作用。

1.介绍

Kratos 一套轻量级 Go 微服务框架,包含大量微服务相关框架及工具。

本文我们分为开发环境,创建项目,代码目录,HTTP API,四个部分介绍 Kratos 微服务框架。

2.开发环境

使用 Kratos 微服务框架,我们需要准备 Go 开发环境,我们选择使用 Go 当前最新版本 go v1.23。

因为 Kratos 微服务框架通过 Protobuf IDL 定义 API,所以我们需要安装工具 protoc,以及相关插件,比如 protoc-gen-go 等。

因为 Kratos 微服务框架使用依赖注入,所以我们需要安装依赖工具 wire。

此外,Kratos 微服务框架提供了脚手架工具 kratos。

3.创建项目

我们可以使用 Kartos 微服务框架的脚手架工具 kratos 创建项目。

示例代码:

kratos new user-center -r https://gitee.com/go-kratos/kratos-layout.git

阅读上面这段代码,我们可以发现使用 kratos 的 new 命令创建项目名称为 user-center 的项目,使用 -r 指定模板源。

此外,也可以使用环境变量指定模板源,例如:KRATOS_LAYOUT_REPO=https://gitee.com/go-kratos/kratos-layout.git。

4.代码目录

在使用 kratos 创建项目之后,我们再介绍一下项目的代码目录。

示例代码:

.
└── user-center
    ├── api
    │   ├── helloworld
    ├── cmd
    │   └── user-center
    ├── configs
    │   └── config.yaml
    ├── Dockerfile
    ├── go.mod
    ├── go.sum
    ├── internal
    │   ├── biz
    │   ├── conf
    │   ├── data
    │   ├── server
    │   └── service
    ├── LICENSE
    ├── Makefile
    ├── openapi.yaml
    ├── README.md
    └── third_party
        ├── errors
        ├── google
        ├── openapi
        ├── README.md
        └── validate

阅读上面的代码目录,我们分别介绍每个目录的作用,api 目录中是 proto 文件以及 protoc 生成的 go 文件;cmd 目录中是项目入口文件 main.go 和 wire 工具的文件 wire.go 以及 wire 生成的 go 文件;configs 目录中是配置文件;

internal 目录中是业务逻辑代码,其中 biz 目录中是 DDD 的 domain 和 usecase,data 目录中是 DDD 的 repository,service 目录中是 DDD 的 delivery;

conf 目录中是使用 proto 格式的配置文件,server 目录中是 http 和 grpc 的实例。

5.HTTP API

创建 proto 文件

Kratos 微服务框架开发 HTTP API 和 RPC API 都是通过定义 proto。

我们可以使用 kratos 脚手架工具生成 proto 模板文件,然后按照自己的需求修改。

示例代码:

kratos proto add api/user/v1/user.proto

也可以手动创建 proto 文件,并且编写相关代码。

示例代码:

syntax = "proto3";

package user.v1;

import "google/api/annotations.proto";

option go_package = "user-center/api/user/v1;v1";

service User {
    rpc Login (LoginReq) returns (LoginRes) {
        option (google.api.http) = {
            post: "/login",
            body: "*",
        }
    }
}

message LoginReq {
    string email = 1;
    string password = 2;
}

message LoginRes {
    string name = 1;
}

在创建 proto 文件之后,我们生成 go 文件,可以直接使用 protoc 工具,也可以使用 kratos 脚手架,本文我们使用 kratos 脚手架。

生成 client 源码

示例代码:

kratos proto client api/user/v1/user.proto

生成 server 源码

示例代码:

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

接入 XORM

修改 internal/data/data.go 文件。

示例代码:

// Data .
type Data struct {
 // TODO wrapped database client
 dbEngine *xorm.Engine
}

// NewData .
func NewData(c *conf.Data, logger log.Logger, dbEngine *xorm.Engine) (*Data, func(), error) {
 cleanup := func() {
  log.NewHelper(logger).Info("closing the data resources")
 }
 return &Data{
  dbEngine: dbEngine,
 }, cleanup, nil
}

// NewDbEngine .
func NewDbEngine(c *conf.Data) (dbEngine *xorm.Engine, err error) {
 dbEngine, err = xorm.NewEngine(c.Database.Driver, c.Database.Source)
 return
}

修改配置文件

修改 configs/config.yaml 文件。

示例代码:

data:
  database:
    driver: mysql
    source: frank:123456@tcp(192.168.110.156:3306)/user?parseTime=True&loc=Local

domain 层和 usecase 层

在 internal/biz/user.go 文件中,编写 domain 层和 usecase 层代码。

示例代码:

package biz

import (
 "context"
 pb "user-center/api/user/v1"
)

type User struct {
 Email    string
 Password string
}

type UserRepo interface {
 Create(ctx context.Context, loginReq *pb.LoginReq) (int64, error)
}

type UserUsecase struct {
 ur UserRepo
}

func NewUserUsecase(ur UserRepo) *UserUsecase {
 return &UserUsecase{
  ur: ur,
 }
}

func (u *UserUsecase) Register(ctx context.Context, loginReq *pb.LoginReq) (id int64, err error) {
 id, err = u.ur.Create(ctx, loginReq)
 return
}

repository 层

在 internal/data/user.go 文件中,编写 reporitory 层代码。

示例代码:

package data

import (
 "context"
 "fmt"
 pb "user-center/api/user/v1"
 "user-center/internal/biz"
)

type userRepo struct {
 data *Data
}

func NewUserRepo(data *Data) biz.UserRepo {
 return &userRepo{
  data: data,
 }
}

func (u *userRepo) Create(ctx context.Context, loginReq *pb.LoginReq) (id int64, err error) {
 fmt.Println(loginReq)
 id, err = u.data.dbEngine.InsertOne(loginReq)
 return
}

delivery 层

在 internal/service/user.go 文件中,编写 delivery 层代码。

示例代码:

package service

import (
 "context"
 "user-center/internal/biz"

 pb "user-center/api/user/v1"
)

// UserService is a user service.
type UserService struct {
 pb.UnimplementedUserServer
 uc *biz.UserUsecase
}

// NewUserService new a user service.
func NewUserService(uc *biz.UserUsecase) *UserService {
 return &UserService{
  uc: uc,
 }
}

// Login implements user.UserService.
func (u *UserService) Login(ctx context.Context, req *pb.LoginReq) (res *pb.LoginRes, err error) {
 _, err = u.uc.Register(ctx, req)
 return
}

注册 HTTP API

在生成 server 源码之后,我们需要注册 HTTP API。

在 internal/server/http.go 文件中,修改代码,导入 v1 blog/api/user/v1 ,在 NewHTTPServer 函数的参数列表中添加 user *service.UserService ,在函数体中添加 v1.RegisterUserHTTPServer(srv, user) 。

wire 生成

接下来,我们需要修改 wire 的 provider。

在 internal/service/service.go 文件中,新增 NewUserService。

示例代码:

var ProviderSet = wire.NewSet(NewGreeterService, NewUserService)

在 internal/biz/biz.go 文件中,新增 NewUserUsecase。

示例代码:

var ProviderSet = wire.NewSet(NewGreeterUsecase, NewUserUsecase)

在 internal/data/data.go 文件中,新增 NewUserRepo。

示例代码:

var ProviderSet = wire.NewSet(NewData, NewDbEngine, NewGreeterRepo, NewUserRepo)

执行 wire 生成命令:

示例代码:

cd cmd/user-center
wire

查看 wire_gen.go 文件。

示例代码:

// wireApp init kratos application.
func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
 engine, err := data.NewDbEngine(confData)
 if err != nil {
  return nil, nil, err
 }
 dataData, cleanup, err := data.NewData(confData, logger, engine)
 if err != nil {
  return nil, nil, err
 }
 greeterRepo := data.NewGreeterRepo(dataData, logger)
 greeterUsecase := biz.NewGreeterUsecase(greeterRepo, logger)
 greeterService := service.NewGreeterService(greeterUsecase)
 grpcServer := server.NewGRPCServer(confServer, greeterService, logger)
 userRepo := data.NewUserRepo(dataData)
 userUsecase := biz.NewUserUsecase(userRepo)
 userService := service.NewUserService(userUsecase)
 httpServer := server.NewHTTPServer(confServer, userService, logger)
 app := newApp(logger, grpcServer, httpServer)
 return app, func() {
  cleanup()
 }, nil
}

阅读上面代码,我们可以发现 wire 工具已经生成依赖注入代码。

运行代码

示例代码:

kratos run

6.总结

本文我们介绍使用 kratos 微服务框架,怎么创建 HTTP API,介绍了怎么通过 kratos 脚手架创建项目和生成 proto 文件。

Kratos 微服务框架使用 DDD 和 DI 的代码架构,我们介绍 kratos 模板生成的代码目录的作用。

关于 proto 和 wire 工具,以及 DDD 和 DI 的详细介绍,我们在之前的文章中都介绍过,读者朋友们可以按需翻阅。

责任编辑:武晓燕 来源: Golang语言开发栈
相关推荐

2024-11-07 11:46:41

2021-07-26 11:19:43

微服务开发技术

2018-12-11 10:43:09

Go语言 HTTP服务器

2023-12-13 07:19:01

微服务架构Golang

2021-09-06 11:34:47

架构微服务Hystrix

2021-03-05 11:09:46

Go框架微服务

2018-01-22 11:50:30

华为云

2020-11-03 09:00:00

API微服务JavaScript框

2017-04-10 20:21:39

Go语言源码分析Handler

2017-04-10 13:26:06

Go语言源码

2018-12-13 09:00:23

GoogleGo微服务

2021-01-14 09:55:21

Java微服务Go

2022-06-08 08:52:04

Tars微服务开发C++开发

2019-05-21 14:01:17

RPC框架Http

2020-09-29 07:00:00

微服务API架构

2012-03-13 10:40:58

Google Go

2015-12-21 14:56:12

Go语言Http网络协议

2013-12-12 10:55:21

2020-11-27 10:50:06

微服务架构框架

2021-03-02 16:25:52

微服务架构技术
点赞
收藏

51CTO技术栈公众号