Зачем использовать ноль
Может быть и третий вариант
- Круг golang невелик, а микросервисных фреймворков всего несколько: кроме go-micro и go-kit других вариантов почти нет. go-zero предоставляет для этого третью возможность.
- go-micro не дружит с поддержкой webapi, ему нужно запускать микроинструкции, которые сложно настроить
Предпринимательским продуктам нужна основа для поддержки роста бизнеса
Какая структура нам нужна? Нам нужна структура, которая может поддерживать рост бизнеса! На ранней стадии эксплуатации продукта, например на этапе проверки требований, нам не нужно внедрять микросервисную архитектуру, поскольку эксплуатационные расходы слишком высоки. Достаточно монолитного приложения. С развитием бизнеса микросервисы становятся необходимыми.На данный момент мы надеемся не выполнять слишком большую нагрузку на код и гибко обновляться. Вот где стоит ноль
Что такое нулевой
Следующие Amway скопированы для конкретной ссылкиhttps://github.com/tal-tech/go-zero
go-zero — это веб- и RPC-фреймворк, объединяющий различные инженерные практики и обладающий следующими основными характеристиками:
- Мощная поддержка инструментов с минимальным кодированием
- Минималистичный интерфейс
- Полностью совместим с сетью/http
- Поддержка промежуточного программного обеспечения для легкого расширения
- высокая производительность
- Программирование, ориентированное на отказ, отказоустойчивая конструкция
- Встроенное обнаружение сервисов, балансировка нагрузки
- Встроенное ограничение тока, плавкие предохранители, сброс нагрузки, автоматический запуск и автоматическое восстановление
- Автоматическая проверка параметров API
- Каскадное управление тайм-аутом
- Автоматический контроль кеша
- Отслеживание ссылок, статистика, сигналы тревоги и т. д.
- Высокая поддержка параллелизма, стабильная и безопасная каждый день во время эпидемии пикового трафика Xiao blackboard
как пользоваться
Прежде чем читать этот документ, обновите golang доgo14
и выше, и включить поддержку модуля go, GO14 и выше предназначены только для поддержки Gorm
export GOPROXY=https://goproxy.io,direct
export GO111MODULE=on
установить гоктл
goctl — это генератор кода для go-zero, в конце концов, ленивый артефакт写代码大多时间是体力活
Как установить?Сначала скачайте исходный код!
git clone https://github.com/tal-tech/go-zero
cd go-zero/tools/goctl
go build goctl.go
Наконец, сгенерируйте копию goctl.exe в$gopath/bin
Вниз
описание команды goctl
Просмотрите документацию самостоятельноhttps://github.com/tal-tech/go-zero/blob/master/tools/goctl/goctl.md
Инструкции, используемые в этой статье, следующие
goctl api go -api open.api -dir .
#代码说明如下
goctl api go -api open.api -dir .
| | | | | | |
生成api go语言 指定api模板文件 模板文件名称 指定生成代码存放路径 当前文件夹
Создать проект
Сгенерировать файл go.mod
Создание проекта с помощью следующей команды
mkdir hello
cd hello
go mod init hello
Определить Hello.API
API, разработанный в этой статье, выглядит следующим образом.
описывать | Формат | метод | параметр | возвращение |
---|---|---|---|---|
Регистрация пользователя | /open/register | post | мобильный: номер мобильного телефона, пароль: пароль, код: код подтверждения изображения | id: ID пользователя, token: токен пользователя |
Логин пользователя | /open/authorization | post | мобильный: номер мобильного телефона, пароль: пароль, код: код подтверждения изображения | id: ID пользователя, token: токен пользователя |
Запрос кода подтверждения изображения | /open/verify | get | билет: идентификатор кода подтверждения изображения | данные: изображения в формате base64 |
Согласно приведенному выше описанию, файл шаблона для написания апи выглядит следующим образом
type (
UserOptReq struct {
mobile string `json:"mobile"`
passwd string `json:"passwd"`
code string `json:"code"`
}
UserOptResp struct {
id uint `json:"id"`
token string `json:"token"`
}
//图片验证码支持
VerifyReq struct {
ticket string `json:"ticket"`
}
//图片验证码支持
VerifyResp struct {
data string `json:"data"`
}
)
service open-api {
@doc(
summary: 公开的api函数
desc: >
register 用户注册,
authorization 用户登录,
verify 图片验证码接口
)
@server(
handler: registerHandler
folder: open
)
post /open/register(UserOptReq) returns(UserOptResp)
@server(
handler: authorizationHandler
folder: open
)
post /open/authorization(UserOptReq) returns(UserOptResp)
@server(
handler: verifyHandler
folder: open
)
post /open/verify(VerifyReq) returns(VerifyResp)
}
Уведомление
- В файле может быть только одна служба
- Инструмент, наконец, сгенерирует различные структуры с моделью типа в качестве шаблона, поэтому параметры и структуры могут быть согласованы.
- Если нам нужно управлять бизнесом в папках, мы можем использовать атрибут папки для определения
сгенерировать код
Создать инструкцию кода
goctl api go -api open.api -dir .
Окончательная структура кода выглядит следующим образом
#tree /F /A
| go.mod
| go.sum
| hello.api
| open.go
|
+---etc
| open-api.yaml
|
\---internal
+---config
| config.go
|
+---handler
| | routes.go
| |
| \---open
| authorizationhandler.go
| registerhandler.go
| verifyhandler.go
|
+---logic
| \---open
| authorizationlogic.go
| registerlogic.go
| verifylogic.go
|
+---svc
| servicecontext.go
|
\---types
types.go
запустить его
go run open.go
пройти тест
curl http://127.0.0.1:8888/open/register -X POST -H "Content-Type: application/json" -d {\"mobile\":\"15367151352\",\"passwd\":\"testpwd\",\"code\":\"asdf\"}
{"id":0,"token":""}
Интегрированный звездный продукт Gorm V2
Босс Jinzhu обновил интеграционный тест Gorm V2
конфигурационный файл
Профилиetc/open-api.yaml
Name: open-api
Host: 0.0.0.0
Port: 8888
DataSourceName: root:1D007648b4f8@(127.0.0.1:3306)/gozero?charset=utf8
существуетetc/open-api.yaml
Добавьте параметр DataSourceName в
существуетinternal/config/config.go
Добавьте имя источника данных в
type Config struct {
rest.RestConf
DataSourceName string
}
По поводу конфигурационного файла, в системе есть встроенные ключевые слова типа Cache, а информации не так много, в принципе, можно настроить по желанию, а потом определить переменную с таким же именем в Conf.
Начать поддержку Горма
Исправлятьsvc/servicecontext.go
код показывает, как показано ниже
package svc
import (
"hello/internal/config"
"hello/internal/models"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type ServiceContext struct {
Config config.Config
DbEngin *gorm.DB
}
func NewServiceContext(c config.Config) *ServiceContext {
//启动Gorm支持
db, err := gorm.Open(mysql.Open(c.DataSourceName), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: "tech_", // 表名前缀,`User` 的表名应该是 `t_users`
SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
},
})
//如果出错就GameOver了
if err != nil {
panic(err)
}
//自动同步更新表结构,不要建表了O(∩_∩)O哈哈~
db.AutoMigrate(&models.User{})
return &ServiceContext{Config: c, DbEngin: db}
}
Новый файл модели
новыйmodels\models.go
документ
//models\models.go文件
package models
import (
"errors"
"hello/internal/utils"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Mobile string `gorm:"index:mobile;type:varchar(13)"`
Passwd string `gorm:"type:varchar(64)"`
}
//在创建前检验验证一下密码的有效性
func (u *User) BeforeCreate(db *gorm.DB) error {
if len(u.Passwd) < 6 {
return errors.New("密码太简单了")
}
//对密码进行加密存储
u.Passwd = utils.Password(u.Passwd)
return nil
}
utils.Password — это инструментарий, который мы написали, код выглядит следующим образом
package utils
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
//密码加密
func Password(plainpwd string) string {
//谷歌的加密包
hash, err := bcrypt.GenerateFromPassword([]byte(plainpwd), bcrypt.DefaultCost) //加密处理
if err != nil {
fmt.Println(err)
}
encodePWD := string(hash) // 保存在数据库的密码,虽然每次生成都不同,只需保存一份即可
return encodePWD
}
//密码校验
func CheckPassword(plainpwd, cryptedpwd string) bool {
err := bcrypt.CompareHashAndPassword([]byte(cryptedpwd), []byte(plainpwd)) //验证(对比)
return err == nil
}
Реализовать бизнес-логику
существуетlogic\open\registerlogic.go
Измените код следующим образом
package logic
import (
"context"
"hello/internal/models"
"hello/internal/svc"
"hello/internal/types"
"github.com/tal-tech/go-zero/core/logx"
)
type RegisterLogic struct {
ctx context.Context
logx.Logger
svcCtx *svc.ServiceContext
}
func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) RegisterLogic {
return RegisterLogic{
ctx: ctx,
Logger: logx.WithContext(ctx),
svcCtx: svcCtx,
}
}
func (l *RegisterLogic) Register(req types.UserOptReq) (*types.UserOptResp, error) {
user := models.User{
Mobile: req.Mobile,
Passwd: req.Passwd,
}
result := l.svcCtx.DbEngin.Create(&user)
return &types.UserOptResp{
Id: user.ID,
}, result.Error
}
- В RegisterLogic добавлен svcCtx * svc.ServiceContext, из-за необходимости использовать внутри DbEngin
- NewRegisterLogic настроить svcCtx
- Реализуйте логику в функции регистрации
result := l.svcCtx.DbEngin.Create(&user)
пройти тест
>curl http://127.0.0.1:8888/open/register -X POST -H "Content-Type: application/json" -d {\"mobile\":\"15367151352\",\"passwd\":\"testpwd\"}
{"id":3,"token":""}
С нетерпением ждем обновленных функций
go-zero
Определение интерфейса хочет поддерживать несколько типов контента.
UserOptReq struct {
mobile string `json:"mobile" form:"mobile" xml:"mobile"`
passwd string `json:"passwd" form:"passwd" xml:"passwd"`
code string `json:"code" form:"code" xml:"code"`
}
Возможный обходной путь
Исправлятьgithub.com/tal-tech/go-zero/rest/httpx/requests.go
серединаParse
в следующую модель
func Parse(r *http.Request, v interface{}) error {
if err := ParsePath(r, v); err != nil {
return err
}
if strings.Contains(r.Header.Get(ContentType), multipartFormData) {
return ParseForm(r, v)
} else if strings.Contains(r.Header.Get(ContentType), urlencodeformdata) {
return ParseForm(r, v)
} else if strings.Contains(r.Header.Get(ContentType), applicationjson) {
return ParseJsonBody(r, v)
} else {
return errors.New("不支持的请求类型")
}
}
Поддерживает несколько методов для каждого файла
Например, следующий способ записи сгенерирует два метода в файле verify Handler.go.
@server(
handler: verifyHandler
folder: open
)
post /open/verify(VerifyReq) returns(VerifyResp)
post /open/authorization(UserOptReq) returns(UserOptResp)
gorm v2
рекомендуемое значение по умолчаниюSingularTable
собственностьtrue
NamingStrategy: schema.NamingStrategy{
TablePrefix: "tech_", // 表名前缀,`User` 的表名应该是 `t_users`
SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
},
Рекомендуется улучшить функцию кеша
Рекомендуется обеспечить поддержку кеша, такого как redis/memcache/memory cache.
Это документ приобретает
Обратите внимание на публичный аккаунтbetaidea
Введите gozero или gormv2, чтобы получить
Широкая реклама
Близятся хорошие новости для пользователей uniapp! После сотен тысяч тестов пользователей наша система обслуживания клиентов, наконец, предоставляет услуги внешнему миру. Вы все еще беспокоитесь о доступе к обслуживанию клиентов в торговом центре?Всего одна строка кода, и вы можете получить к нему доступ!! Всего одна строчка кода!!!!
/*kefu.vue*/
<template>
<view>
<IdeaKefu :siteid="siteId" ></IdeaKefu>
</view>
</template>
<script>
import IdeaKefu from "@/components/idea-kefu/idea-kefu.vue"
export default {
components:{
IdeaKefu
},
data() {
return {
siteId:2
}
}
}
Эффект отличный
Адрес документа разработкиkefu.techidea8.com/html/wiki/