当前位置:网站首页>Kratos战神微服务框架(二)
Kratos战神微服务框架(二)
2022-07-06 08:59:00 【~庞贝】
Kratos战神微服务框架(二)
项目结构

api编写
protobuf编写
syntax = "proto3";
package realworld.v1;
import "google/api/annotations.proto";
option go_package = "realworld/api/realworld/v1;v1";
// The greeting service definition.
service RealWorld {
rpc Login(LoginRequest) returns (UserReply) {
option (google.api.http) = {
post: "/api/users/login",
body: "*", // 注意post请求一定交加body项
};
}
}
message LoginRequest{
message User {
string email = 1;
string password = 2;
}
User user = 1;
}
message UserReply {
message User {
string email = 1;
string token = 2;
string username = 3;
string bio = 4;
string image = 5;
}
User user = 1;
}
使用makefile
注:需要安装make指令
GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
API_PROTO_FILES=$(shell find api -name *.proto)
.PHONY: init
# init env
init:
go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]
go install github.com/go-kratos/kratos/cmd/kratos/[email protected]
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/[email protected]
go install github.com/google/gnostic/cmd/[email protected]
.PHONY: config
# generate internal proto
config:
protoc --proto_path=./internal \
--proto_path=./third_party \
--go_out=paths=source_relative:./internal \
./internal/conf/*.proto
# $(INTERNAL_PROTO_FILES)
.PHONY: api
# generate api proto
api:
protoc --proto_path=./api \
--proto_path=./third_party \
--go_out=paths=source_relative:./api \
--go-http_out=paths=source_relative:./api \
--go-grpc_out=paths=source_relative:./api \
--openapi_out=fq_schema_naming=true,default_response=false:. \
./api/realworld/v1/*.proto
# $(API_PROTO_FILES)
.PHONY: build
# build
build:
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...
.PHONY: generate
# generate
generate:
go mod tidy
go get github.com/google/wire/cmd/[email protected]
go generate ./...
.PHONY: wire
# wire
wire:
cd cmd/realworld/ && wire
.PHONY: run
# run
run:
kratos run
.PHONY: all
# generate all
all:
make api;
make config;
make generate;
# show help
help:
@echo ''
@echo 'Usage:'
@echo ' make [target]'
@echo ''
@echo 'Targets:'
@awk '/^[a-zA-Z\-\_0-9]+:/ { \
helpMessage = match(lastLine, /^# (.*)/); \
if (helpMessage) { \
helpCommand = substr($$1, 0, index($$1, ":")-1); \
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
} \
} \
{ lastLine = $$0 }' $(MAKEFILE_LIST)
.DEFAULT_GOAL := help
注:默认是linux命令,windwos需要修改路径
service层接口实现
进入internal/service目录
service.go
package service
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
v1 "helloworld/api/realworld/v1"
"helloworld/internal/biz"
)
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewRealWorldService) //依赖注入
type RealWorldService struct {
v1.UnimplementedRealWorldServer
pu *biz.SocialUsecase
uc *biz.UserUsecase
log *log.Helper
}
func NewRealWorldService(uc *biz.UserUsecase, logger log.Logger) *RealWorldService {
return &RealWorldService{
uc: uc, log: log.NewHelper(logger)}
}
//实现方法
func (s *RealWorldService) Login(ctx context.Context, req *v1.LoginRequest) (*v1.UserReply, error) {
return &v1.UserReply{
User: &v1.UserReply_User{
Username: "jtyyds",
},
}, nil
}
biz层
package biz
import "github.com/google/wire"
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewSocialUsecase, NewUserUsecase) //依赖注入
type User struct {
Email string
Username string
Bio string
Image string
PasswordHash string
}
type UserLogin struct {
Email string
Username string
Token string
Bio string
Image string
}
// bcrypt方法加密
func hashPassword(pwd string) string {
password, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
if err != nil {
panic(err)
}
fmt.Printf("%v", password)
return string(password)
}
// 密码进行比较
func verifyPassword(hashed, input string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashed), []byte(input))
if err != nil {
return false
}
return true
}
// 接口方法
type UserRepo interface {
CreateUser(ctx context.Context, user *User) error
GetUserByEmail(ctx context.Context, email string) (*User, error)
}
type ProfileRepo interface {
}
type UserUsecase struct {
ur UserRepo
pr ProfileRepo
jwtc *conf.JWT
log *log.Helper
}
func NewUserUsecase(ur UserRepo, pr ProfileRepo, jwtc *conf.JWT, logger log.Logger) *UserUsecase {
return &UserUsecase{
ur: ur, pr: pr, jwtc: jwtc, log: log.NewHelper(logger)}
}
func (uc *UserUsecase) generateToken(username string) string {
return auth.GenerateToken(uc.jwtc.Token, username)
}
// 注册的业务逻辑
func (uu *UserUsecase) Register(ctx context.Context, username, email, password string) (*UserLogin, error) {
u := &User{
Email: email,
Username: username,
PasswordHash: hashPassword(password),
}
if err := uu.ur.CreateUser(ctx, u); err != nil {
return nil, err
}
return &UserLogin{
Email: email,
Username: username,
Token: uu.generateToken(username),
}, nil
}
// 登录的业务逻辑实现
func (uu *UserUsecase) Login(ctx context.Context, email, password string) (*UserLogin, error) {
u, err := uu.ur.GetUserByEmail(ctx, email)
if err != nil {
return nil, err
}
b := verifyPassword(u.PasswordHash, password)
if b == true {
return nil, errors.New("Loin")
}
return &UserLogin{
Email: u.Email,
Username: u.Username,
Bio: u.Bio,
Image: u.Image,
Token: uu.generateToken(u.Username),
}, nil
}
data层
data.go
package data
import (
"fmt"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"helloworld/internal/conf"
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewDB, NewUserRepo, NewProfileRepo) //依赖注入
// Data .
type Data struct {
// TODO wrapped database client
db *gorm.DB
}
// NewData .
func NewData(c *conf.Data, logger log.Logger, db *gorm.DB) (*Data, func(), error) {
cleanup := func() {
log.NewHelper(logger).Info("closing the data resources")
}
return &Data{
db: db}, cleanup, nil
}
// 连接mysql数据库
func NewDB(c *conf.Data) *gorm.DB {
fmt.Println(c.Database.Dsn)
db, err := gorm.Open(mysql.Open(c.Database.Dsn), &gorm.Config{
})
if err != nil {
panic("failed")
}
if err := db.AutoMigrate(); err != nil {
panic(err)
}
return db
}
package data
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"helloworld/internal/biz"
)
type userRepo struct {
data *Data
log *log.Helper
}
func NewUserRepo(data *Data, logger log.Logger) biz.UserRepo {
return &userRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (r *userRepo) CreateUser(ctx context.Context, g *biz.User) error {
// 可以实现操作数据库,这个并没有实现
return nil
}
func (r *userRepo) GetUserByEmail(ctx context.Context, email string) (*biz.User, error) {
// 可以实现操作数据库,这个并没有实现
return nil, nil
}
configs配置文件
server:
http:
addr: 0.0.0.0:8000
timeout: 1s
grpc:
addr: 0.0.0.0:9000
timeout: 1s
data:
database:
driver: mysql
dsn: "root:[email protected](127.0.0.1:3306)/realworld?charset=utf8mb4&parseTime=True&loc=Local"
jwt:
secret : "hello"
修改配置文件后,需要修改internal/conf下的conf.proto
syntax = "proto3";
package kratos.api;
option go_package = "helloworld/internal/conf;conf";
import "google/protobuf/duration.proto";
message Bootstrap {
Server server = 1;
Data data = 2;
JWT jwt = 3;
}
message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message GRPC {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
HTTP http = 1;
GRPC grpc = 2;
}
message Data {
message Database {
string driver = 1;
string dsn = 2;
}
Database database = 1;
}
message JWT {
string token = 1;
}
使用make config生成conf.pb.go
注:是否需要修改config的makefile
边栏推荐
- Pytorch view tensor memory size
- LeetCode:498. Diagonal traversal
- LeetCode:221. Largest Square
- CUDA realizes focal_ loss
- 不同的数据驱动代码执行相同的测试场景
- Intel distiller Toolkit - Quantitative implementation 1
- [text generation] recommended in the collection of papers - Stanford researchers introduce time control methods to make long text generation more smooth
- Tdengine biweekly selection of community issues | phase III
- pytorch查看张量占用内存大小
- Advanced Computer Network Review(4)——Congestion Control of MPTCP
猜你喜欢

The carousel component of ant design calls prev and next methods in TS (typescript) environment

数学建模2004B题(输电问题)

In depth analysis and encapsulation call of requests

Intel distiller Toolkit - Quantitative implementation 1

BN折叠及其量化

Intel distiller Toolkit - Quantitative implementation 2

Chapter 1 :Application of Artificial intelligence in Drug Design:Opportunity and Challenges
![[OC-Foundation框架]---【集合数组】](/img/b5/5e49ab9d026c60816f90f0c47b2ad8.png)
[OC-Foundation框架]---【集合数组】

Selenium+pytest automated test framework practice

IJCAI2022论文合集(持续更新中)
随机推荐
LeetCode:26. Remove duplicates from an ordered array
LeetCode:41. 缺失的第一个正数
注意力机制的一种卷积替代方式
MongoDB 的安装和基本操作
xargs命令的基本用法
【shell脚本】使用菜单命令构建在集群内创建文件夹的脚本
【shell脚本】——归档文件脚本
Redis之Bitmap
Basic usage of xargs command
LeetCode:41. Missing first positive number
Parameterization of postman
LeetCode:162. Looking for peak
【每日一题】搬运工 (DFS / DP)
Go redis initialization connection
requests的深入刨析及封装调用
Show slave status \ read in G_ Master_ Log_ POS and relay_ Log_ The (size) relationship of POS
如何正确截取字符串(例:应用报错信息截取入库操作)
LeetCode:394. 字符串解码
Leetcode: Jianzhi offer 03 Duplicate numbers in array
UML图记忆技巧