当前位置:网站首页>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-Foundation框架]-<字符串And日期与时间>
- LeetCode:39. Combined sum
- [OC]-<UI入门>--常用控件-UIButton
- 【shell脚本】——归档文件脚本
- [shell script] use menu commands to build scripts for creating folders in the cluster
- 【shell脚本】使用菜单命令构建在集群内创建文件夹的脚本
- Leetcode刷题题解2.1.1
- How to intercept the string correctly (for example, intercepting the stock in operation by applying the error information)
- UML图记忆技巧
猜你喜欢

Advanced Computer Network Review(3)——BBR

Intel distiller Toolkit - Quantitative implementation 1

Pytest参数化你不知道的一些使用技巧 /你不知道的pytest

How to intercept the string correctly (for example, intercepting the stock in operation by applying the error information)

QDialog
![[shell script] - archive file script](/img/50/1bef6576902890dfd5771500414876.png)
[shell script] - archive file script

Advanced Computer Network Review(4)——Congestion Control of MPTCP

CUDA realizes focal_ loss

Pytest's collection use case rules and running specified use cases

A convolution substitution of attention mechanism
随机推荐
Basic usage of xargs command
多元聚类分析
Advanced Computer Network Review(3)——BBR
[oc]- < getting started with UI> -- learning common controls
Pytest's collection use case rules and running specified use cases
LeetCode41——First Missing Positive——hashing in place & swap
Improved deep embedded clustering with local structure preservation (Idec)
Connexion d'initialisation pour go redis
Cesium draw points, lines, and faces
Selenium+Pytest自动化测试框架实战(下)
Intel distiller Toolkit - Quantitative implementation 1
Go redis initialization connection
MongoDB 的安装和基本操作
LeetCode:39. Combined sum
Super efficient! The secret of swagger Yapi
QML control type: Popup
数字人主播618手语带货,便捷2780万名听障人士
I-BERT
Multivariate cluster analysis
pytorch查看张量占用内存大小