当前位置:网站首页>Kratos ares microservice framework (II)
Kratos ares microservice framework (II)
2022-07-06 09:13:00 【~Pompeii】
Kratos Ares microservice framework ( Two )
Catalog
Project structure
api To write
protobuf To write
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: "*", // Be careful post The request must be crossed body term
};
}
}
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;
}
Use makefile
notes : Need to install make Instructions
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
notes : The default is linux command ,windwos You need to change the path
service Layer interface implementation
Get into internal/service Catalog
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) // Dependency injection
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)}
}
// Implementation method
func (s *RealWorldService) Login(ctx context.Context, req *v1.LoginRequest) (*v1.UserReply, error) {
return &v1.UserReply{
User: &v1.UserReply_User{
Username: "jtyyds",
},
}, nil
}
biz layer
package biz
import "github.com/google/wire"
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewSocialUsecase, NewUserUsecase) // Dependency injection
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 Method encryption
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)
}
// Compare passwords
func verifyPassword(hashed, input string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashed), []byte(input))
if err != nil {
return false
}
return true
}
// Interface method
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)
}
// Registered business logic
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
}
// Login business logic implementation
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 layer
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) // Dependency injection
// 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
}
// Connect mysql database
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 {
// It can operate the database , This has not been achieved
return nil
}
func (r *userRepo) GetUserByEmail(ctx context.Context, email string) (*biz.User, error) {
// It can operate the database , This has not been achieved
return nil, nil
}
configs The configuration file
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"
After modifying the configuration file , Need modification internal/conf Under the 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;
}
Use make config Generate conf.pb.go
notes : Need to modify config Of makefile
边栏推荐
猜你喜欢
[OC]-<UI入门>--常用控件的学习
[oc foundation framework] - < copy object copy >
Redis cluster
[MySQL] multi table query
Opencv+dlib realizes "matching" glasses for Mona Lisa
Redis之持久化实操(Linux版)
BMINF的後訓練量化實現
UML圖記憶技巧
Pytest之收集用例规则与运行指定用例
[text generation] recommended in the collection of papers - Stanford researchers introduce time control methods to make long text generation more smooth
随机推荐
KDD 2022 paper collection (under continuous update)
【每日一题】搬运工 (DFS / DP)
Connexion d'initialisation pour go redis
Using C language to complete a simple calculator (function pointer array and callback function)
IJCAI2022论文合集(持续更新中)
LeetCode:236. The nearest common ancestor of binary tree
BN folding and its quantification
Redis cluster
Redis之持久化实操(Linux版)
[OC-Foundation框架]--<Copy对象复制>
[OC-Foundation框架]-<字符串And日期与时间>
LeetCode:124. Maximum path sum in binary tree
Intel distiller Toolkit - Quantitative implementation 1
Selenium+Pytest自动化测试框架实战
postman之参数化详解
Blue Bridge Cup_ Single chip microcomputer_ PWM output
五层网络体系结构
[MySQL] multi table query
[OC]-<UI入门>--常用控件-提示对话框 And 等待提示器(圈)
SAP ui5 date type sap ui. model. type. Analysis of the parsing format of date