SoFunction
Updated on 2025-03-03

Detailed explanation of the example of sharing variable Context using GoFrame

Preface Summary

Yesterday, I encountered many conflicts with my colleague's merge code. I found that some of the previous methods wrote the parameters that were not standardized and did not pass in the Context, which was inconvenient for link tracking. He reviews the project code and basically adds Context parameters to all methods in the project.

Today I will introduce to you the use of Context and tell you what Context is? How to use it? Why use Context and tips and issues in use.

What is a Context?

ContextRefers to the standard library, is an interface object, often used for asynchronousIOControl and the delivery of context process variables.

What this article will introduce isContextHow to pass variables in business processes elegantly and why variables need to be passed.

Why do you need a Context?

existGoIn the execution process, especiallyHTTP/RPCIn the execution process, there is no way to obtain the request parameters by "global variables", only through the context.ContextThe variables are passed into the method of subsequent processes.

How does Context implement shared variables?

andContextContext variables include all shared variables that need to be passed.

And theContextShared variables in it are agreed in advance and are often stored as object pointers.

How to use it?

passContextContext shared variables are very simple. Here is an example to learn how to pass and use common shared variables.

1. Structural definition

Context objects often store variables that need to be shared, which are usually stored using structured objects for easy maintenance.

For example, wemodelDefine a shared variable in a context:

const (
	// Context variables store key names, shared by front and back end systems	ContextKey = "ContextKey"
)
// Request context structuretype Context struct {
	Session * // Current Session Management Object	User    *ContextUser   // Context user information	Data              // Custom KV variables, business modules are set as needed, not fixed}
// Request user information in the contexttype ContextUser struct {
	Id       uint   // User ID	Passport string // User account	Nickname string // User name	Avatar   string // User avatar}

introduce

Constants are stored inThe key name in the context variable that is used to pass fromStore/get business custom shared variables in variables.

In the structureSessionIndicates the current requestSessionObject, inGoFrameEach in the frameworkHTTPThere will be an empty request objectSessionObject, which adopts a lazy initialization design and will only be initialized when reading and writing operations are actually performed.

In the structureUserIndicates the basic information of the currently logged in user, and data will only be available after the user logs in, otherwisenil

In the structureDataProperties are used to store customKVVariables, so generally speaking, developers do not need to goAdd custom key-value pairs to context variables, but use them directlymodel.``ContextThis object'sDataJust attributes.

2. Logical encapsulation

Since this context object is also related to business logic, we need to useserviceObjects encapsulate context variables for easy use by other modules.

// Context Management Servicevar Context = new(contextService)
type contextService struct{}
// Initialize the context object pointer into the context object so that it can be modified in subsequent request flows.func (s *contextService) Init(r *, customCtx *) {
	(, customCtx)
}
// Get the context variable, if not set, then return nilfunc (s *contextService) Get(ctx ) * {
	value := ()
	if value == nil {
		return nil
	}
	if localCtx, ok := value.(*); ok {
		return localCtx
	}
	return nil
}
// Set the context information into the context request, note that it is full coveragefunc (s *contextService) SetUser(ctx , ctxUser *) {
	(ctx).User = ctxUser
}

Tips

In architectural design, it is very critical to set the Context in which scenario.

Context variables must be injected into the request process at the beginning of the request to facilitate other method calls, so it is a very elegant choice to implement in middleware.

Let's take a look at the introduction below:

3. Context variable injection

existHTTPWe can use it during the requestGoFramemiddleware to implement.

existGRPCWe can also use an interceptor to implement the request.

existserviceLayermiddlewareIn the management object, we can define it like this:

// Custom context objectfunc (s *middlewareService) Ctx(r *) {
	// Initialization, be sure to execute first	customCtx := &{
		Session: ,
		Data:    make(),
	}
	(r, customCtx)
	if userEntity := (()); userEntity != nil {
		 = &{
			Id:       ,
			Passport: ,
			Nickname: ,
			Avatar:   ,
		}
	}
	// Pass custom context objects to template variables for use	({
		"Context": customCtx,
	})
	// Execute the next request logic	()
}

This middleware initializes the object shared by the user's execution process and stores it toThe object in a variable is a pointer type*

The advantage of doing this is that if you obtain this pointer anywhere, you can not only obtain the data inside, but also directly modify the data inside.

TIPS

ifSessionThere are stored information after the user login, and the basic user information that needs to be shared will be written to*middle.

IV. Use of context variables

Method definition

The first input parameter defined by the method is often reserved forType parameters are used to accept context variables, especiallyservicelayer method.

For example:

// Perform user loginfunc (s *userService) Login(ctx , loginReq *) error {
    ...
}
// Query content listfunc (s *contentService) GetList(ctx , r *) (*, error) {
    ...
}
// Create reply contentfunc (s *replyService) Create(ctx , r *) error {
    ...
}

TIPS

Another good habit is: the last return parameter of the method is oftenerrortype. If you determine that the method will never be generatederror, then it can be ignored.

Context object acquisition

passserviceThe following method of encapsulation willJust pass the context variables in.

The context variable isGoFrameFrameworkHTTPCan be passed during the request()Method to obtain.

existGRPCIn the request, compiled and generatedpbThe first parameter of the execution method in the file is fixed

(ctx)

Custom Key-Value

We can set/get customkey-valueKey-value pairs.

// Set custom key-value pairs(ctx).Data[key] = value
...go
// Get custom key-value pairs(ctx).Data[key]

5. Pay attention to problems

  • The context variable only passes the necessary link parameter data, and do not plug all parameters into it. In particular, some method parameters and data of transfer parameters must not be stuffed into the context, but should be displayed.
  • Context variables are only used temporarily at runtime and cannot be used for persistent storage for long-term use.

Summarize

This article introduces you in detail the knowledge points of the GoFrame context object Context:

The role of Context: Share variables in business processes.

Context structure definition, logical encapsulation, how to inject it into middleware, how to set and get values ​​through Context, how to customize key-value in Context, and what to note when using it in project development. For more information about GoFrame shared variable Context, please pay attention to my other related articles!