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个条件模型开发的,是用于诊断团队有效性的测评工具,其建构过程严格遵循心理测量学原理。可以帮助企业觉察团队优劣势,找到提升与发展机会,明确和强化…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
