Backend Development 8 min read

Mastering Gobox: A Go Lightweight Framework for Seamless HTTP Routing

This article introduces Gobox, a self‑developed lightweight Go framework that treats each module as a reusable box, explains its HTTP request handling architecture—including System, Router, SimpleRouter, ActionContext, and Controller components—provides detailed code snippets, routing rules, and a complete example with graceful server restart support.

360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
Mastering Gobox: A Go Lightweight Framework for Seamless HTTP Routing

Gobox Overview

Gobox is a lightweight Go framework where each independent module is packaged as a box . All boxes together form the Gobox framework, which can be imported into a project using Go's package management. With Go's dep tool, each box can be managed as a separate project.

HTTP Request Handling Architecture

The framework provides several core objects:

System : Implements the http.Handler interface and defines the ServeHTTP method.

Router : Defines and implements the MVC routing lookup process.

Router Interface

<code>type Router interface {
    MapRouteItems(cls ...controller.Controller) // automatically map Controller actions to the routing table
    DefineRouteItem(pattern string, cl controller.Controller, actionName string) // manually add a route rule, pattern is a regular expression
    FindRoute(path string) *Route // perform route lookup
}
</code>

SimpleRouter Implementation

SimpleRouter automatically maps routes based on naming conventions:

Controller name must match ([A‑Z][A‑Za‑z0‑9_]*)Controller$ ; the matched part (lower‑cased) becomes the controller name.

Action name must match ([A‑Z][A‑Za‑z0‑9_]*)Action$ ; after lower‑casing and removing the before and after suffixes, the remaining part is the action name.

Automatic routing rules:

The request URI is interpreted as /controller/action .

If the controller does not exist, it defaults to index (configurable).

If the action does not exist, it defaults to index (configurable).

Custom routing can use regular expressions; captured groups become additional string parameters passed to the action.

ActionContext and Controller

For each request, an ActionContext object is created to hold request and response data.

<code>type ActionContext interface {
    Request() *http.Request
    ResponseWriter() http.ResponseWriter
    ResponseBody() []byte
    SetResponseBody(body []byte)
    BeforeAction()
    AfterAction()
    Destruct()
}
</code>

The Controller interface creates a new ActionContext for a request.

<code>type Controller interface {
    NewActionContext(req *http.Request, respWriter http.ResponseWriter) ActionContext
}
</code>

A base implementation provides common fields and methods.

<code>type BaseActionContext struct {
    Req        *http.Request
    RespWriter http.ResponseWriter
    RespBody   []byte
}

func (c *BaseActionContext) Request() *http.Request { return c.Req }
func (c *BaseActionContext) ResponseWriter() http.ResponseWriter { return c.RespWriter }
func (c *BaseActionContext) ResponseBody() []byte { return c.RespBody }
func (c *BaseActionContext) SetResponseBody(body []byte) { c.RespBody = body }
func (c *BaseActionContext) BeforeAction() { c.RespBody = append(c.RespBody, []byte(" index before ")...) }
func (c *BaseActionContext) AfterAction() { c.RespBody = append(c.RespBody, []byte(" index after ")...) }
func (c *BaseActionContext) Destruct() { println(" index destruct ") }
</code>

Example controllers:

<code>type IndexController struct{}

func (c *IndexController) NewActionContext(req *http.Request, respWriter http.ResponseWriter) ActionContext {
    return &BaseActionContext{Req: req, RespWriter: respWriter}
}

func (c *IndexController) IndexAction(ctx *BaseActionContext) {
    ctx.RespBody = append(ctx.RespBody, []byte(" index action ")...)
}

func (c *IndexController) RedirectAction(ctx *BaseActionContext) {
    // use system to issue a 302 redirect
    system.Redirect302("https://github.com/goinbox")
}
</code>

Graceful HTTP Server (gracehttp)

The framework includes gracehttp , which supports smooth server restarts without dropping connections.

Graceful HTTP server diagram
Graceful HTTP server diagram

Complete Example

<code>package main

import (
    "github.com/goinbox/gohttp/controller"
    "github.com/goinbox/gohttp/gracehttp"
    "github.com/goinbox/gohttp/router"
    "github.com/goinbox/gohttp/system"
    "net/http"
)

func main() {
    dcl := new(DemoController)
    r := router.NewSimpleRouter()
    r.DefineRouteItem("^/g/([0-9]+)$", dcl, "get")
    r.MapRouteItems(new(IndexController), dcl)
    sys := system.NewSystem(r)
    gracehttp.ListenAndServe(":8001", sys)
}

// ... (DemoController, DemoActionContext, IndexController definitions as shown above)
</code>

Running the program yields responses such as:

<code>curl http://127.0.0.1:8001/ → "index before  index action  index after "
curl -I http://127.0.0.1:8001/index/redirect → 302 Found with Location header pointing to https://github.com/goinbox
curl http://127.0.0.1:8001/demo/demo → "demo before  demo action  demo after"
curl http://127.0.0.1:8001/g/123 → "demo before  get action id = 123 demo after"
</code>

All Destruct methods output their respective messages when the request handling finishes.

Feel free to use Gobox in your projects and report any issues for quick assistance.

backendGoRoutingHTTPframeworkGraceful Restart
360 Zhihui Cloud Developer
Written by

360 Zhihui Cloud Developer

360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.