go-zero中统一返回前端数据格式的几种方式
方式一、直接定义一个成功和失败的方法,在代码里面修改(对代码有侵入,每次都要修改代码)
-
1、封装一个统一返回的方法
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、修改代码的返回值方法调用
func GetTestHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {l := demo.NewGetTestLogic(r.Context(), svcCtx)resp, err := l.GetTest()if err != nil {//httpx.ErrorCtx(r.Context(), w, err)utils.Fail(w, err.Error())} else {//httpx.OkJsonCtx(r.Context(), w, resp)utils.Success(w, resp)}} }
方式二、在api文件定义的时候直接返回的数据结构(在定义api的时候繁琐了)
-
1、
api文件中定义type Response {Code string `json:"code"`Msg string `json:"msg"`Data interface{} `json:"data"` }@server (prefix: demo/v1group: demo ) service demo-api {@doc "测试"@handler GetTestget /testApi returns (Response)} -
2、在每次操作的时候可以写上
func (l *GetTestLogic) GetTest() (resp *types.Response, err error) {return &types.Response{Code: "0",Msg: "成功",Data: "hello world",}, nil } -
3、参考官网地址
方式三、自定义模版,直接修改返回的数据方法(可以接受)
-
1、定义方法
package utilsimport ("encoding/json""encoding/xml""errors""github.com/zeromicro/go-zero/core/logx""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 json里面加了这个表示如果为空的时候字段不返回 }type PageVo struct {Data interface{} `json:"data"` // 数据Total int64 `json:"total"` // 总条数PageSize int64 `json:"pageSize"` // 当前条数PageNumber int64 `json:"pageNumber"` // 当前页数 }// Response 一般返回 func Response(w http.ResponseWriter, resp interface{}, err error) {if err != nil {httpx.OkJson(w, Body{Code: 1,Message: err.Error(),Result: nil,})} else {httpx.OkJson(w, Body{Code: 0,Message: "请求成功",Result: resp,})} }// BuildPageData 返回分页数据 func BuildPageData(w http.ResponseWriter, resp interface{}, total, pageSize, pageNumber int64, err error) {if err != nil {httpx.OkJson(w, Body{Code: 1,Message: err.Error(),Result: PageVo{Data: nil, // 数据Total: 0, // 总条数PageSize: pageSize, // 当前条数PageNumber: pageNumber, // 当前页数},})} else {httpx.OkJson(w, Body{Code: 0,Message: "请求成功",Result: PageVo{Data: resp, // 数据Total: total, // 总条数PageSize: pageSize, // 当前条数PageNumber: pageNumber, // 当前页数},})} }func WriteString(w http.ResponseWriter, code int, v string) {w.Header().Set("Content-Type", "text/plain; charset=utf-8")w.WriteHeader(code)if n, err := w.Write([]byte(v)); err != nil {// http.ErrHandlerTimeout has been handled by http.TimeoutHandler,// so it's ignored here.if !errors.Is(err, http.ErrHandlerTimeout) {logx.Errorf("write response failed, error: %s", err)}} else if n < len(v) {logx.Errorf("actual bytes: %d, written bytes: %d", len(v), n)} }func WriteXml(w http.ResponseWriter, code int, v interface{}) {bs, err := xml.Marshal(v)if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)return}w.Header().Set("Content-Type", "text/xml")w.Header().Set("response_body", string(bs))w.WriteHeader(code)if n, err := w.Write(bs); err != nil {// http.ErrHandlerTimeout has been handled by http.TimeoutHandler,// so it's ignored here.if !errors.Is(err, http.ErrHandlerTimeout) {logx.Errorf("write response failed, error: %s", err)}} else if n < len(bs) {logx.Errorf("actual bytes: %d, written bytes: %d", len(bs), n)} }func WriteFile(w http.ResponseWriter, fileBytes []byte, err error) {var (b []byte)if err != nil {httpx.OkJson(w, err)b, _ = json.Marshal(err)w.Header().Set("response_body", string(b))return}w.Header().Set("Content-Type", "application/octet-stream")if n, err := w.Write(fileBytes); err != nil {// http.ErrHandlerTimeout has been handled by http.TimeoutHandler,// so it's ignored here.if !errors.Is(err, http.ErrHandlerTimeout) {logx.Errorf("write response failed, error: %s", err)}} else if n < len(fileBytes) {logx.Errorf("actual bytes: %d, written bytes: %d", len(fileBytes), n)}w.WriteHeader(200) } -
2、定义模版
handler.tplpackage {{.PkgName}}import ("net/http""github.com/zeromicro/go-zero/rest/httpx"{{.ImportPackages}} )func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {{{if .HasRequest}}var req types.{{.RequestType}}if err := httpx.Parse(r, &req); err != nil {utils.TranslatorError(w, r, err)return}{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx){{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}}){{if .HasResp}}utils.Response(w, resp, err){{else}}utils.Response(w, nil, err){{end}}} } -
3、使用自己的模版生成方法
goctl api go -api *api --dir . --style=goZero --home ../../goctl -
4、生成的代码中
func DemoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {var req types.Requestif err := httpx.Parse(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return}l := demo.NewDemoLogic(r.Context(), svcCtx)resp, err := l.Demo(&req)utils.Response(w, resp, err)} } -
5、这种方式不好的地方,在每个项目中导包可能不一样的,需要手动改动模版,或者把封装的方法封装成一个库发布
方式四、使用拦截器(最优方案)
-
1、创建自己返回的方法
package utilsimport ("context""github.com/zeromicro/go-zero/core/logx""net/http" )type Response struct {Code int64 `json:"code"`Message string `json:"message"`Result interface{} `json:"result,omitempty"` }func Success(data interface{}) *Response {return &Response{Code: 0,Message: "请求成功",Result: data,} }func Fail(err string) *Response {return &Response{Code: 1,Message: err,Result: nil,} }func OkHandler(_ context.Context, v interface{}) any {return Success(v) }func ErrHandler(name string) func(ctx context.Context, err error) (int, any) {return func(ctx context.Context, err error) (int, any) {// 日志记录logx.WithContext(ctx).Errorf("【%s】 err %v", name, err)return http.StatusBadRequest, Fail(err.Error())} } -
2、在项目启动文件中添加自己的方法

// 使用拦截器
httpx.SetOkHandler(utils.OkHandler)
httpx.SetErrorHandlerCtx(utils.ErrHandler(c.Name))
相关文章:
go-zero中统一返回前端数据格式的几种方式
方式一、直接定义一个成功和失败的方法,在代码里面修改(对代码有侵入,每次都要修改代码) 1、封装一个统一返回的方法 package utilsimport ("github.com/zeromicro/go-zero/rest/httpx""net/http" )type Body struct {Code int json:"code…...
【向量数据库】Ubuntu编译安装FAISS
参考官方的安装指导:https://github.com/facebookresearch/faiss/blob/main/INSTALL.md,不需要安装的可以跳过 ~$ wget https://github.com/facebookresearch/faiss/archive/refs/tags/v1.8.0.tar.gz ~$ tar -zxvf v1.8.0.tar.gz ~$ cd faiss-1.8.0 ~$ …...
制造知识普及(九)--企业内部物料编码(IPN)与制造商物料编码(MPN)
在日常的物料管理业务逻辑中,一物一码是物料管理的基本的业务规则,不管物料从产品开发还是仓库管理,甚至成本核算,都要遵循这个原则,才能保证产品数据的准确性,才具备唯一追溯的可行性。大部分企业都是这种…...
【整数规划】+【0—1规划】解决优化类问题(Matlab代码)
目录 文章目录 前言 一、整数规划 分类: 二、典例讲解 1.背包问题 2.指派问题 总结 前言 如果觉得本篇文章还不错的话,给作者点个赞鼓励一下吧😁😁😁 在规划问题中,有些最优解可能是分数或小数&am…...
Linux下如何使用Curl进行网络请求
在Linux系统上,Curl是一个非常强大的网络请求工具,可以用于发送各种类型的HTTP请求,并获取响应结果。它支持常见的HTTP方法,如GET、POST、PUT、DELETE等,还支持HTTPS、FTP等不同协议。Curl提供了丰富的参数选项&#x…...
PostgreSQL 触发器
PostgreSQL 触发器 PostgreSQL触发器是一种强大的数据库对象,它可以在特定的数据库事件发生时自动执行预定义的操作。这些事件可以是插入、更新或删除表中的行。触发器通常用于强制复杂的业务规则、提供审计跟踪、数据同步以及实现复杂的约束。 触发器的基本概念 …...
LeetCode——3131.找出与数组相加的整数I
通过万岁!!! 题目:给你两个数组nums1和nums2,然后让你找一个数,使得nums1的数加上这个数以后得到的数组nums1’与nums2是相同的。注意这里只要元素相同就好了,不一定顺序相同。思路:…...
【SpringMVC】详细了解SpringMVC中WEB-INF 目录资源,视图解析器和静态资源放行的使用。
目录 1. 回顾SpringMVC请求转发和重定向 2. WEB-INF资源目录 3. 视图解析器 4. 静态资源放行 1. 回顾SpringMVC请求转发和重定向 概念:在一个项目中功能非常多,也就意味着有非常多的Servlet,不同的Servlet的职不 同 ,而用户发起…...
如何学好uni-app
学习uni-app需要掌握以下技能: 1. 前端基础:熟悉HTML、CSS和JavaScript等前端开发技术,了解基本的前端框架如Vue.js。 2. Vue.js:因为uni-app是基于Vue.js构建的,所以需要对Vue.js有深入的理解。可以先通过官方文档或者…...
C++ QT使用stackwidget实现页面切换(含源码)
C++ QT使用stackwidget实现页面切换(含源码) 0.前言1.UI布局1.1使用stackwidget2.代码方式添加页面实现页面切换3.源码4.最终效果0.前言 在QT中一个界面中如何实现页面的切换,而不是新弹出的窗口,这里采用的stackwidget,以层叠widget的方式选定页面索引从而实现页面切换。…...
打工人上班适合用的蓝牙耳机推荐?几款开放式耳机推荐
日常工作的话,我还是比较推荐开放式蓝牙耳机的,它特别适合那些需要在长时间工作中保持专注和舒适度的环境,那开放式耳机其实还有一些主要的优点: 减少耳朵疲劳:由于开放式耳机不需要紧密贴合耳朵,因此可以…...
一款.NET开发的AI无损放大工具
一款.NET开发的AI无损放大工具 思维导航 前言项目功能支持语言系统要求项目源代码项目运行小图片进行无损放大项目源码地址优秀项目和框架精选 前言 今天大姚给大家分享一款由.NET开源(GPL-3.0 license)、基于腾讯ARC Lab提供的Real-ESRGAN模型开发的A…...
编程新手必看:彻底理解!与~的取反操作
在编程和计算机科学的语境中,! 和 ~ 都是取反操作符,但它们的应用方式和效果存在显著的区别。下面将从定义、应用场景、作用原理及示例等方面对 ! 和 ~ 进行详细解析。 一、定义 !(逻辑非运算符) 在C语言、Java等多数编程语言中&…...
【LeetCode】54. 螺旋矩阵
螺旋矩阵 题目描述: 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]示例 2:…...
计算机毕业设计 奖学金评定管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
【JavaWeb项目】——外卖订餐系统之商家添加餐品、修改餐品、查询热卖餐品、查询出售车、进行发货操作
🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL࿰…...
制作抖音私信卡片 - 一键调起并跳转微信二维码
抖音私信图文卡片,点击可以直接一键添加微信 可生成无风险链接,使用苹果手机转发创建出卡片 抖音内点击可以直接调起微信跳入小程序展示微信二维码...
赋能未来园区:TSINGSEE视频AI智能管理平台如何引领园区管理智慧化转型
一、建设背景 随着经济的不断发展,园区产业集聚发展已成为趋势,园区逐渐成为产业聚集的重要载体。目前,国内现有的大部分园区的管理方式比较粗放、单一,范围局限于安全、环境等方面且不成体系,并且没有覆盖到应急、消…...
Linux逻辑卷管理LVM
系列文章目录 提示:仅用于个人学习,进行查漏补缺使用。 1.Linux介绍、目录结构、文件基本属性、Shell 2.Linux常用命令 3.Linux文件管理 4.Linux 命令安装(rpm、install) 5.Linux账号管理 6.Linux文件/目录权限管理 7.Linux磁盘管理/文件系统 提示&a…...
团队诊断工具TDS
希典梁开广老师引进的团队诊断问卷TDS(Team Diagnostic Survey)是基于卓越团队6个条件模型开发的,是用于诊断团队有效性的测评工具,其建构过程严格遵循心理测量学原理。可以帮助企业觉察团队优劣势,找到提升与发展机会,明确和强化…...
机械臂轨迹规划中的S型速度优化算法设计与实现
1. 机械臂轨迹规划的核心挑战 机械臂运动控制中最关键的问题之一,就是如何让机械臂在保证平稳运行的前提下,以最短时间完成指定轨迹。想象一下工厂里的机械臂在流水线上快速精准地抓取零件——这个看似简单的动作背后,隐藏着复杂的运动学计算…...
基于QT(C++)+Oracle实现的(界面)教务管理系统
一、选题背景 教务管理系统是基本每个高校都有的一个系统,教务系统管理系统充分利用互联网络B/S管理系统模式,以网络为平台,为各个学校教务系统的管理提供一个平台,帮助学校管理教务,用一个账号解决学校教务教学管理&…...
还在手动拖动进度条整理长视频总结?2026年这4款AI视频总结工具,3分钟搞定1小时长片
我做内容创作快五年,光整理音视频素材这块,踩过的坑能绕办公桌三圈。之前天天手动拖进度条截重点,一小时长视频整理完大半天就没了。测了市面上十多款热门AI视频总结工具,我可以直接给结论:听脑AI是同类工具中最值得用…...
OpenClaw技能组合技:用SecGPT-14B实现ATTCK框架检测
OpenClaw技能组合技:用SecGPT-14B实现ATT&CK框架检测 1. 为什么需要自动化安全检测 去年处理某次安全事件时,我花了整整三天手工比对日志中的异常行为与ATT&CK框架。这种重复劳动让我开始思考:能否让AI自动完成TTPs(战术…...
HiFloat8:高性能训练之路
Float8单数据格式FP8/HiF8训练算法介绍Float8混合精度训练策略随着预训练模型(尤其是基于Transformer架构的大语言模型)参数规模突破千亿级,训练过程面临愈发严重的算力和内存瓶颈,成本极高。在此背景下,8位浮点逐渐成…...
Qwen3-VL:30B部署实操:Clawdbot配置文件详解、飞书Bot权限申请与事件订阅最佳实践
Qwen3-VL:30B部署实操:Clawdbot配置文件详解、飞书Bot权限申请与事件订阅最佳实践 1. 项目概述与准备工作 1.1 项目介绍 本项目将带你从零开始,在CSDN星图AI云平台上私有化部署最强的多模态大模型Qwen3-VL:30B,并通过Clawdbot搭建一个既能…...
别再只用协同过滤了!聊聊Spark电商推荐系统中的‘冷启动’与实时推荐那些事儿
突破传统推荐瓶颈:Spark电商系统中的冷启动与实时推荐实战解析 1. 电商推荐系统的演进与挑战 在数字化消费时代,推荐系统已成为电商平台的核心竞争力。从早期的简单规则推荐到如今的深度学习模型,推荐技术经历了三次重要迭代: 第一…...
让AI成为你的数据库设计师:使用快马平台智能规划与优化数据模型
让AI成为你的数据库设计师:使用快马平台智能规划与优化数据模型 最近在开发一个在线教育平台时,我深刻体会到数据库设计的重要性。合理的表结构和关系设计不仅能提高查询效率,还能减少后期维护的复杂度。幸运的是,我发现InsCode(…...
信号处理避坑指南:一维小波去噪中那些容易忽略的细节
信号处理避坑指南:一维小波去噪中那些容易忽略的细节 在信号处理领域,小波去噪因其优异的时频局部化特性,成为处理非平稳信号的首选方法。然而,许多工程师在应用PyWavelets等工具库时,往往陷入"调参陷阱"——…...
如何用iTorrent在iPhone上轻松管理种子下载?iOS种子客户端全攻略
如何用iTorrent在iPhone上轻松管理种子下载?iOS种子客户端全攻略 【免费下载链接】iTorrent Torrent client for iOS 16 项目地址: https://gitcode.com/gh_mirrors/it/iTorrent iTorrent是一款专为iOS 16设备设计的开源种子客户端,让iPhone和iPa…...
