Sitemap

The Complete Guide to GoFr Context

3 min readDec 22, 2023
Press enter or click to view image in full size

GoFr Context is a custom implementation of context specifically designed for use within the framework. Along with the standard Go context features, it offers additional features and benefits tailored to GoFr’s microservice development philosophy.

Moreover, the gofr.Context object stands as a pivotal entity, seamlessly weaving its way through every handler. It acts as a custodian of request-specific elements, ensuring each request-response cycle possesses a unique context tailored to its needs. GoFr meticulously crafts this context, thoughtfully populating it with dependencies like loggers, datastores, and more—all meticulously configured based on your project's specifications.

Here’s what makes GoFr Context significant:

  • Initialization and Configuration:

GoFr locates the config folder, reads the environment variables, and proceeds to validate its contents. Upon encountering a valid configuration, GoFr proceeds to initialize supported resources, such as databases, making them accessible through the context.

Upon invoking gofr.New(), GoFr initializes the following components based on your configuration:

  • Logger — It is initialized when the app is initialised and the same instance of it is used across the complete application.
// accessing gofr logger
logger := app.Logger
or
logger := ctx.Logger
  • Datastores /Pub-Sub — GoFr also supports multiple datastores, which can be initialized on server start by defining the required configs. After this the corresponding methods can be accessed and consumed from the handler’s context.
// to access SQL datastores
ctx.DB().QueryContext()
// to access Redis
ctx.Redis
.
.
.
// Similarly other datastores are accessed

// to subscribe to a topic whose configs have been added in .env
message, err := ctx.Subscribe(&p)
if err != nil {
return nil, err
}
  • Trace— GoFr sends the trace span, if tracing configurations are configured. By default it sends spans for the time taken at different steps.
    If custom span has to be added in a particular method, it can be done by using context in the following way.
    Which will start appearing in the final trace.

span := ctx.Trace(“some-sample-work”)
// some logic
span.End()
  • Custom context values:

Beyond just deadlines and cancellations, GoFr Context allows storing arbitrary key-value pairs, enabling developers to attach application-specific data relevant to their microservices. This facilitates sharing information between handlers and services without resorting to global variables or other techniques.

  • Cancellation integration with graceful shutdown

Like the standard Go context, GoFr Context supports cancellation, allowing upstream services to signal termination to downstream services. This enables graceful shutdown of microservices during server termination or restarts, avoiding data inconsistencies and partial operations.

  • Unifying Request Handling

Every GoFr handler adheres to a consistent signature:

func (*gofr.Context) (interface{}, error)

This signature underscores the integral role of gofr.Context in GoFr's request handling process. It serves as a unifying vessel, encapsulating the request, response, and all associated dependencies, making them readily accessible within handlers.

// Retrieve path parameters:
pathParam := ctx.PathParam("key")

// Retrieve query parameters:
queryParam := ctx.Param("param1")
queryParams := ctx.Params() // Fetch all query parameters as a map

// Access HTTP headers:
header := ctx.Header("content-type")

// Decode request bodies:
type User struct {
Name string `json:"name"`
}
var u User
ctx.Bind(&u) // Bind JSON or XML to struct
ctx.BindStrict(&u) // Enforce strict data binding rules

// Access the raw request object:
req := ctx.Request()

Grasping Multipart Form Data:

// Access multipart-form files:
files := ctx.Request().MultipartForm.File
values := ctx.Request().MultipartForm.Value

// Retrieve specific values:
file, header, err := ctx.Request().FormFile("key")
value := ctx.Request().FormValue("key")

Conclusion

Overall, GoFr Context plays a crucial role in simplifying and streamlining microservice development within the GoFr framework by:

  • Improving code organization and separation of concerns.
  • Facilitating efficient data sharing and dependency injection.
  • Enabling graceful shutdown and error handling.

If you’re interested in learning more about GoFr Context and how it works within the GoFr framework, I recommend checking out the following resources:

I hope this explanation clarifies the significance of GoFr Context! Feel free to ask any further questions you might have.

--

--