Goframe学习笔记(六)上下文共享变量

文章目录

官方文档: Context: 业务流程共享变量 - GoFrame (ZH)-Latest - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架

Context

在Go的执行流程中,不存在全局变量这种获取请求参数的方式,但可以通过上下文Context将所有需要传递的共享变量传递到后续流程的方法中。

结构定义

结构体中需要包含业务中传递的信息,这里包含了会话(Session)、用户信息(User)以及一个键值对映射(Data)。

新建model/context.go文件:

复制代码
├── model
│   |   ├── do
│   │   ├── entity
│   │   └── context.go
go 复制代码
package model

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

const (
	// 上下文变量存储键名,前后端系统共享
	ContextKey = "ContextKey"
)

// 请求上下文结构
type Context struct {
	Session *ghttp.Session // 当前Session管理对象
	User    *ContextUser   // 上下文用户信息
	Data    g.Map          // 自定KV变量,业务模块根据需要设置,不固定
}

// 请求上下文中的用户信息
type ContextUser struct {
	Id       uint   // 用户ID
	Passport string // 用户账号
	Nickname string // 用户名称
	Avatar   string // 用户头像
}

逻辑封装

封装上下文的相关操作。这包括初始化上下文、获取上下文和设置用户信息等功能。

新建logic/context/context.go文件

复制代码
├── logic
│   │   ├── context
│   │   │   └── context.go
│   │   └── logic.go
go 复制代码
package context

import (
	"context"
	"demo/internal/model"
	"demo/internal/service"

	"github.com/gogf/gf/v2/net/ghttp"
)

func init() {
	service.RegisterContext(New())
}

type sContext struct{}

func New() *sContext {
	return &sContext{}
}

// 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改。
func (s *sContext) Init(r *ghttp.Request, customCtx *model.Context) {
	r.SetCtxVar(model.ContextKey, customCtx)
}

// 获得上下文变量,如果没有设置,那么返回nil
func (s *sContext) Get(ctx context.Context) *model.Context {
	value := ctx.Value(model.ContextKey)
	if value == nil {
		return nil
	}
	if localCtx, ok := value.(*model.Context); ok {
		return localCtx
	}
	return nil
}

// 将上下文信息设置到上下文请求中,注意是完整覆盖
func (s *sContext) SetUser(ctx context.Context, ctxUser *model.ContextUser) {
	s.Get(ctx).User = ctxUser
}

上下文变量注入

上下文变量的注入通过定义一个中间件来实现。这个中间件在请求的最开始执行,用于初始化上下文,将请求中携带的参数置入结构体中,以便后续的处理函数可以便捷调用。

新建logic/middleware/middleware.go文件

复制代码
├── logic
│   │   ├── context
│   │   ├── middleware
│   │   │   └── middleware.go
│   │   └── logic.go
go 复制代码
package middleware

import (
	"demo/internal/model"
	"demo/internal/service"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

type sMiddleware struct{}

func init() {
	service.RegisterMiddleware(New())
}

func New() *sMiddleware {
	return &sMiddleware{}
}

func (*sMiddleware) Ctx(r *ghttp.Request) {
	// 初始化,务必最开始执行
	customCtx := &model.Context{
		Session: r.Session,
		Data:    make(g.Map),
	}
	service.Context().Init(r, customCtx)

	// TODO 获取用户信息
	// ...

	// 将自定义的上下文对象传递到模板变量中使用
	r.Assigns(g.Map{
		"Context": customCtx,
	})
	// 执行下一步请求逻辑
	r.Middleware.Next()
}

上下文变量使用

约定方法定义的第一个输入参数预留给context.Context类型参数使用,以便接受上下文变量。例如:

go 复制代码
func (s *xxx) func1(ctx context.Context, xxxxReq *xxx.xxxxReq) error {
    ...
}

可以通过以下方式获取上下文:

go 复制代码
service.Context().Get(ctx)

可以通过 Data 字段存储和获取自定义的键值对数据:

go 复制代码
// 设置自定义键值对
service.Context.Get(ctx).Data[key] = value
// 获取自定义键值对
service.Context.Get(ctx).Data[key]
相关推荐
La Pulga2 小时前
【FreeRTOS源码学习笔记】任务延时列表
笔记·mcu·学习·嵌入式·freertos·实时操作系统
楚山之石3 小时前
【JCO】mpMRI 先行替代 TURBT 初始分期:BladderPath 随机试验让 MIBC 患者提前 45 天得到正确治疗
人工智能·学习·mri·医学影像
Peter-OK7 小时前
PostgreSQL学习笔记(入门-进阶-精通说明)
笔记·学习·postgresql
承渊政道7 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
橙橙笔记8 小时前
具身智能的学习 - 完成一个机械臂 第1节
python·学习·机械臂·具身智能
成都蜀味缘餐饮技术培训学校9 小时前
手撕烤兔技术培训实战指南,秘制腌料配方比例与调制手法
大数据·经验分享·笔记·其他·微信公众平台
希和202710 小时前
免费AI视频生成工具汇总(国内优先,适合做漫剧、短视频,Obsidian笔记版)
人工智能·笔记·音视频
蒸蒸yyyyzwd11 小时前
秋招学习笔记 day109
笔记·八股
Hhy_110712 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
山甫aa13 小时前
锁一篇搞定:乐观锁、悲观锁、CAS、数据库锁与分布式锁【从零开始的 Web 后端学习】
java·数据库·分布式·后端·学习·web