go zero手把手教你入门案例

一、入门案例

  • 1、在黑窗口上安装

    go install github.com/zeromicro/go-zero/tools/goctl@latest
    
  • 2、使用goland创建一个项目

  • 3、在项目中安装依赖

    go get -u github.com/zeromicro/go-zero@latest
    
  • 4、模拟创建一个user的项目

    goctl api new user
    
  • 5、安装依赖包

    go mod tidy
    
  • 6、补充代码段

    func (l *UserLogic) User(req *types.Request) (resp *types.Response, err error) {// todo: add your logic here and delete this linereturn &types.Response{Message: "你好,水痕",}, nil
    }
    
  • 7、在浏览器上输入http://localhost:8888/from/me,关于为什么是me可以查看types.go文件

    package typestype Request struct {Name string `path:"name,options=you|me"`
    }
    
  • 8、关于user项目目录解说

    .
    ├── etc
    │   └── user-api.yaml # 配置文件
    ├── internal 
    │   ├── config
    │   │   └── config.go
    │   ├── handler
    │   │   ├── routes.go # 路由文件
    │   │   └── userhandler.go # 可以理解为控制层
    │   ├── logic
    │   │   └── userlogic.go # 可以理解为服务层
    │   ├── svc
    │   │   └── servicecontext.go
    │   └── types
    │       └── types.go # 可以理解为DTO、VO
    ├── user.api
    └── user.go # 启动文件7 directories, 9 files
    

二、自己编写api文件来生成别的文件

  • 1、创建一个空的module项目

  • 2、在根目录下创建一个user.api的文件

    type LoginRequest {Username string `json:"username"`Password string `json:"password"`
    }type LoginResponse {Code    int64  `json:"code"`Data    string `json:"data"`Message string `json:"message"`
    }type UserInfo {Id       int64  `json:"id"`Username string `json:"username"`
    }type UserInfoResponse {Code    int64    `json:"code"`Data    UserInfo `json:"data"`Message string   `json:"message"`
    }
    // 定义要被方法的方法
    service users {@handler loginpost /api/users/login (LoginRequest) returns (LoginResponse)@handler userInfoget /api/users/userInfo returns (UserInfoResponse)
    }
    
  • 3、执行脚本

    goctl api go -api user.api -dir .
    
  • 4、等生成文件后,安装依赖包

  • 5、书写一个获取用户信息的代码

    
    func (l *UserInfoLogic) UserInfo() (resp *types.UserInfoResponse, err error) {// todo: add your logic here and delete this linereturn &types.UserInfoResponse{Code:    0,Message: "请求成功",Data: types.UserInfo{Id:       1,Username: "水痕",},}, nil
    }
    
  • 6、运行启动

三、封装自定义返回模板

  • 1、创建一个utils的文件夹

    package utilsimport ("github.com/zeromicro/go-zero/rest/httpx""net/http"
    )type Body struct {Code    int         `json:"code"`Message string      `json:"message"`Result  interface{} `json:"result,omitempty"`
    }func Response(w http.ResponseWriter, code int, message string, data interface{}) {httpx.OkJson(w, Body{Code:    code,Message: message,Result:  data,})
    }// Success 成功的请求
    func Success(w http.ResponseWriter, data interface{}) {Response(w, 0, "请求成功", data)
    }// Fail 失败的请求
    func Fail(w http.ResponseWriter, message string) {Response(w, 1, message, nil)
    }
    
  • 2、定义api的时候就可以去除这些固定的写法

    type LoginRequest {Username string `json:"username"`Password string `json:"password"`
    }type UserInfoResponse {Id       int64  `json:"id"`Username string `json:"username"`
    }
    // 定义要被方法的方法
    service users {@handler loginpost /api/users/login (LoginRequest) returns (string )@handler userInfoget /api/users/userInfo returns (UserInfoResponse)
    }
    
  • 3、重新执行转换脚本

    goctl api go -api user.api -dir .
    
  • 4、改写代码,后运行

四、统一前缀

  • 1、上面每次在service里面都要写/api/users/这个路径,如果都是一样的,可以提取出去统一到前面

    // 定义要被方法的方法
    @server(prefix: /api/users
    )
    service users {@handler loginpost /login (LoginRequest) returns (string)@handler userInfoget /userInfo returns (UserInfoResponse)
    }
    
  • 2、重新转换下

五、jwt的使用

  • 1、改写user.api文件

    type LoginRequest {Username string `json:"username"`Password string `json:"password"`
    }type UserInfoResponse {Id       int64  `json:"id"`Username string `json:"username"`
    }
    // 定义要被方法的方法
    @server(prefix: /api/users
    )
    service users {@handler loginpost /login (LoginRequest) returns (string)
    }@server(prefix: /api/usersjwt: Auth
    )
    service users {@handler userInfoget /userInfo returns (UserInfoResponse)
    }
    
  • 2、重新执行转换文件的脚本

    goctl api go -api user.api -dir .
    goctl api go -api *.api -dir .
    
  • 3、在etc/users.yaml文件中添加jwt的配置

    Name: users
    Host: 0.0.0.0
    Port: 8888
    Auth:AccessSecret: test1test1  # 随机一个数就可以AccessExpire: 3600 # 过期时间
    
  • 4、在internal/config/config.go中配置,任何在yaml中添加的配置都要在config.go中添加配置

    package configimport "github.com/zeromicro/go-zero/rest"type Config struct {rest.RestConfAuth struct {AccessSecret stringAccessExpire int64}
    }
    
  • 5、在utils文件夹下创建一个jwt.go的文件

    package utilsimport ("errors""github.com/golang-jwt/jwt/v4""time"
    )// JwtPayLoad jwt中payload数据
    type JwtPayLoad struct {UserID   uint   `json:"userId"`   // 用户idUsername string `json:"username"` // 用户名
    }type CustomClaims struct {JwtPayLoadjwt.RegisteredClaims
    }// GenToken 创建 Token
    func GenToken(user JwtPayLoad, accessSecret string, expires int64) (string, error) {claim := CustomClaims{JwtPayLoad: user,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * time.Duration(expires))),},}token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)return token.SignedString([]byte(accessSecret))
    }// ParseToken 解析 token
    func ParseToken(tokenStr string, accessSecret string, expires int64) (*CustomClaims, error) {token, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {return []byte(accessSecret), nil})if err != nil {return nil, err}if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {return claims, nil}return nil, errors.New("invalid token")
    }
    
  • 6、在登录的时候返回token给前端

    func (l *LoginLogic) Login(req *types.LoginRequest) (resp string, err error) {// TODO 模拟查询数据库操作if req.Username == "admin" && req.Password == "123456" {auth := l.svcCtx.Config.Authtoken, err := utils.GenToken(utils.JwtPayLoad{UserID:   1,Username: req.Username,}, auth.AccessSecret, auth.AccessExpire)if err != nil {fmt.Println("生成token失败")return "", errors.New("账号或密码错误")}return token, nil} else {return "", errors.New("账号或密码错误")}
    }
    
  • 7、在需要从token中获取用户信息

    func (l *UserInfoLogic) UserInfo() (resp *types.UserInfoResponse, err error) {// todo: add your logic here and delete this line// 从请求头中获取token,解析出来userId := l.ctx.Value("userId").(json.Number)fmt.Println(userId)fmt.Printf("数据类型:%v,%T\n", userId, userId)username := l.ctx.Value("username").(string)fmt.Println(username)uid, _ := userId.Int64()return &types.UserInfoResponse{Id:       uid,Username: username,}, nil
    }
    
  • 8、登录接口生成token

  • 9、测试获取用户信息

    {"Authorization":"Bearer eyJhbGciOiJIUzI1Ni"
    }
    

    在这里插入图片描述

六、获取客户端参数

  • 1、获取path参数,url上请求的地址为:``,这里xx就是要获取的地址

    type MessageReq {Id int64  `path:"id"`
    }
    @server(prefix: /api/messages
    )
    service users {@handler messageget /message/:id(MessageReq) returns (string)
    }
    
  • 2、获取query参数,url上请求的地址为localhost:8888/api/message?name=xx&age=zz

    type MessageInfoReq {Name string `form:"name"`Age int64 `form:"age"`
    }@server(prefix: /api/messages
    )
    service users {@handler messageInfoget /messageInfo(MessageInfoReq) returns (string)
    }
    
  • 3、获取post提交的json数据

    type LoginRequest {Username string `json:"username"`Password string `json:"password"`
    }@server(prefix: /api/users
    )
    service users {@handler loginpost /login (LoginRequest) returns (string)
    }
    
  • 4、接收方法根据转码后会自动生成,且都是一样的

    var req types.MessageReq
    if err := httpx.Parse(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return
    }
    // 直接从req中获取数据就可以
    

七、一个项目下多个api文件

  • 1、在实际开发中,我更喜欢一张表就对应一个api文件,这样更好维护,唯一注意点就是每个文件里面的service users这个users是要一样的就可以,实际根据你项目来写的

  • 2、在根目录下创建一个api的文件夹,里面包括message.apiuser.api

  • 3、message.api文件内容

    syntax = "v2"type MessageInfoReq {Name string `form:"name,default=word"`Age int64 `form:"age,default=20"`
    }type MessageReq {Id int64  `path:"id"`
    }
    @server(prefix: /api/messages
    )
    service users {@handler messageInfoget /messageInfo(MessageInfoReq) returns (string)@handler messageget /message/:id(MessageReq) returns (string)
    }
    
  • 4、user.api文件内容

    syntax = "v2"type LoginRequest {Username string `json:"username"`Password string `json:"password"`
    }type UserInfoResponse {Id       int64  `json:"id"`Username string `json:"username"`
    }
    // 定义要被方法的方法
    @server(prefix: /api/users
    )
    service users {@handler loginpost /login (LoginRequest) returns (string)
    }@server(prefix: /api/usersjwt: Auth
    )
    service users {@handler userInfoget /userInfo returns (UserInfoResponse)
    }
    
  • 5、根目录下创建一个api.api的文件

    syntax = "v2"import "api/user.api"
    import "api/message.api"
    
  • 6、运行转码命令

    goctl api go -api api.api -dir .
    # 或者直接使用下面的
    goctl api go -api *.api -dir .
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/190033.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue项目本地开发完成后部署到服务器后报404

vue项目本地开发完成后部署到服务器后报404是什么原因呢? 一、如何部署 前后端分离开发模式下,前后端是独立布署的,前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后,是生成一系…

Guitar Pro2024吉他软件好不好用?

吉他,这把魔幻的弹奏利器,既需要技术,又需要技巧。 是的,它不会自己跳入你的手中,除非你敲对了密码:练习! 今天就来看看,大家是不是已经找到了快速掌握吉他的门道呢? …

【DataV可视化工具详解】

文章目录 前言一、什么是DataV?二、主要特点1. 强大的图表库2. 灵活的数据接入3.实时数据展示4. 易于定制的仪表盘 三、应用场景1.业务监控与分析2.大屏展示3.数据洞察与决策支持 四、例图总结我是将军,我一直都在,。! 前言 今天…

Vatee万腾的科技征程:Vatee数字化创新的前沿探讨

在Vatee万腾的科技征程中,我们目睹了一场数字化创新的引领之旅,探讨了Vatee在科技前沿的独到见解。Vatee万腾不仅仅是一家科技公司,更是一支前行不辍的冒险队伍,通过不断突破自我,探索未知领域,引领着数字化…

Vue3 动态设置 ref

介绍 在一些场景,ref设置是未知的需要根据动态数据来决定,如表格中的input框需要我们主动聚焦,就需要给每一个input设置一个ref,进而进行聚焦操作。 Demo 点击下面截图中的编辑按钮,自动聚焦到相应的输入框中。 &…

UnoCss(原子化css引擎) 让你的开发更轻松愉快

什么是原子化CSS,UnoCSS又是什么,对此有疑问的推荐看下antfu的这篇文章——重新构想原子化 CSS (antfu.me) 相信看完这篇文章的你也会跟我一样热衷于UnoCSS. 介绍 今天介绍一个CSS开发利器 UnoCSS , 是一个具有高性能且极具灵活性的即时原子化 CSS 引擎…

《洛谷深入浅出基础篇》——P3405 citis and state ——哈希表

上链接:P3405 [USACO16DEC] Cities and States S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3405 上题干: 题目描述 Farmer John 有若干头奶牛。为了训练奶牛们的智力,Farmer John 在谷仓的墙上放了一…

ceph学习笔记

ceph ceph osd lspoolsrbd ls -p testpool#查看 ceph 集群中有多少个 pool,并且每个 pool 容量及利 用情况 rados dfceph -sceph osd tree ceph dfceph versionsceph osd pool lsceph osd crush rule dumpceph auth print-key client.adminceph orch host lsceph crash lsceph…

python计算脚长 青少年电子学会等级考试 中小学生python编程等级考试一级真题答案解析2022年9月

目录 python字符串输出 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python字符串输出 2022年9月 python编程等级考试一级编程…

基于Zemax的高能激光发射系统的扩束系统设计

关键词:高功率激光发射系统;扩束系统 1 引言 高功率激光发射系统是强激光空间传输系统中不可缺少的装置。对高功率激光发射系统的研究一直是激光应用领域的关键技术问题。高功率激光发射系统通常由准直系统、导光光路系统和扩束系统组成,光学系统要求具…

【docker】Docker网络与iptables

Docker能为我们提供很强大和灵活的网络能力,很大程度上要归功于与iptables的结合。在使用时,你可能没有太关注到 iptables在其中产生的作用,这是因为Docker已经帮我们自动的完成了相关的配置。 iptables在Docker中的应用主要是用于网络流量控…

三十二、W5100S/W5500+RP2040树莓派Pico<UPnP示例>

文章目录 1 前言2 简介2 .1 什么是UPnP?2.2 UPnP的优点2.3 UPnP数据交互原理2.4 UPnP应用场景 3 WIZnet以太网芯片4 UPnP示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 随着智能家居、物联网等…