solanum

package module
v0.5.0-rc2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2026 License: MIT Imports: 5 Imported by: 2

README

Solanum — A Modular Gin-Based Web Framework

Solanum is a lightweight framework built on top of Gin that helps Go developers build clean, maintainable HTTP services and micro-APIs with explicit structure and flow.

Instead of hiding control flow behind containers or implicit wiring, Solanum encourages clear module boundaries, predictable routing, and readable composition.


Why Solanum?

A typical Gin application often grows into:

  • A massive main.go that wires routes, middleware, and handlers inline
  • Implicit control flow that’s hard to follow once the project grows
  • Business logic spread across handlers with no clear module boundaries
  • Boilerplate duplicated across services and endpoints

Solanum addresses these problems by focusing on:

1. Explicit Flow Over Magic

All routes, handlers, and middleware are registered explicitly. There is no hidden resolution or automatic injection —
what you write is exactly what runs.

2. Modular Structure

Routes are grouped into self-contained Modules. Each module owns its routing prefix, controllers, and middleware.

3. Predictable Composition

Applications are composed step by step: modules → controllers → handlers → server. You can trace request flow by reading the code top to bottom.

4. Test-Friendly Design

Because handlers and services are constructed explicitly, you can test them in isolation without bootstrapping the entire server.


What Can You Build?

  • RESTful APIs
  • Microservices
  • GraphQL or gRPC gateways
  • Admin or internal tools
  • Web servers for applications
    • Health checks
    • Metrics
    • Admin dashboards

Solanum scales from a single /ping endpoint to multi-module services without changing how you structure your code.


Core Principles

  • Explicit is better than implicit
  • Composition over configuration
  • No hidden lifecycle or control flow
  • Readable code beats clever abstractions

Solanum does not try to replace Gin — it provides a clear structure around it.


Key Features

1. Modular Architecture
// Define a /users module
userModule := solanum.NewModule(
    solanum.WithUri("/users"),
)
userModule.SetControllers(myUserController)

Each module:

  • Owns its route prefix
  • Registers its controllers explicitly
  • Can be reasoned about independently
2. Controller-Centered Routing
type SolaService struct {
    Uri     string
    Method  string
    Handler gin.HandlerFunc
}

Controllers define:

  • HTTP method
  • Relative URI
  • Handler function

No reflection-based routing, no annotations — just plain Go structures.

3. Module-Level Middleware

Each module supports pre-middleware (runs before the handler) and post-middleware (runs after the handler).

module := solanum.NewModule(
    solanum.WithUri("/users"),
)

// Pre-middleware: executed before the handler
module.SetPreMiddlewares(authMiddleware, loggingMiddleware)

// Post-middleware: executed after the handler
module.SetPostMiddlewares(responseLogger)

// You can also append individual middleware
module.AddPreMiddleware(rateLimiter)
module.AddPostMiddleware(metricsCollector)

The final handler chain for each route is: pre-middlewares → handler → post-middlewares.

4. Application-Level CORS
import "github.com/annuums/solanum/middleware/cors"

server.Cors(
  cors.WithUrls([]string{"https://example.com"}),
  cors.WithMethods([]string{"GET", "POST"}),
  cors.WithAllowCredentials(true),
)

CORS middleware is applied at the application level using functional options. Sensible defaults are provided for headers and methods when not specified.


Getting Started

Get Solanum
go get github.com/annuums/solanum
Easy Start
package main

import (
  "net/http"

  "github.com/annuums/solanum"
  "github.com/gin-gonic/gin"
)

func main() {

  pingModule := solanum.NewModule(
    solanum.WithUri("/ping"),
  )

  ctrl := solanum.NewController()
  ctrl.SetHandlers(
    &solanum.SolaService{
      Uri:    "",
      Method: http.MethodGet,
      Handler: func(c *gin.Context) {
        c.String(http.StatusOK, "pong")
      },
    },
  )
   
  pingModule.SetControllers(ctrl)

  server := solanum.NewSolanum(
    solanum.WithPort(5050),
  )

  server.SetModules(pingModule)
  server.Run()
}

Every step is explicit:

  • Module creation
  • Controller registration
  • Handler definition
  • Server composition

No hidden wiring. No surprises.

Examples & More

See the Simple Example for a minimal health-check server.

Who Is This For?

  • Go developers who value explicit control flow
  • Teams building REST APIs or microservices with Gin
  • Projects that want structure without heavy frameworks
  • Engineers who prefer readable composition over implicit behavior

If you believe that clarity beats convenience, Solanum is for you.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithUri added in v0.4.4

func WithUri(uri string) moduleOption

Types

type Controller

type Controller interface {
	// Handlers returns the slice of service definitions this controller manages.
	Handlers() []*SolaService

	// SetHandlers replaces the controller's service handlers with the provided list.
	SetHandlers(handler ...*SolaService)
}

Controller declares a set of service handlers for a logical grouping of routes.

type Module

type Module interface {
	// PreMiddlewares returns middleware to run before each handler.
	PreMiddlewares() []gin.HandlerFunc

	// AddPreMiddleware appends a middleware to the pre-handler chain.
	AddPreMiddleware(middleware gin.HandlerFunc)

	// SetPreMiddlewares replaces the entire pre-handler middleware chain.
	SetPreMiddlewares(middlewares ...gin.HandlerFunc)

	// PostMiddlewares returns middleware to run after each handler.
	PostMiddlewares() []gin.HandlerFunc

	// AddPostMiddleware appends a middleware to the post-handler chain.
	AddPostMiddleware(middleware gin.HandlerFunc)

	// SetPostMiddlewares replaces the entire post-handler middleware chain.
	SetPostMiddlewares(middlewares ...gin.HandlerFunc)

	// Controllers returns the slice of Controller implementations in this module.
	Controllers() []Controller

	// SetControllers replaces all Controller implementations for this module.
	SetControllers(c ...Controller)

	// AddControllers appends one or more Controller implementations to this module.
	AddControllers(c ...Controller)

	// SetRoutes binds the module's controllers, middleware, and routes onto a RouterGroup.
	SetRoutes(router *gin.RouterGroup)

	// Uri returns the base URI path for this module (e.g., "/users").
	Uri() string
}

Module represents a self-contained HTTP module with its own URI prefix, middleware layers, controllers, and dependencies.

type Option

type Option func(*runner)

func WithPort added in v0.4.4

func WithPort(port int) Option

type Runner

type Runner interface {
	// InitModules sets up all registered modules and their routes.
	InitModules()

	// InitGlobalMiddlewares registers any application-wide middleware.
	InitGlobalMiddlewares()

	// Modules returns a slice of pointers to registered Modules.
	Modules() []Module

	// SetModules registers one or more Modules with the Runner.
	SetModules(m ...Module)

	// GinEngine exposes the underlying *gin.Engine for custom setup.
	GinEngine() *gin.Engine

	// Port exposes the configured port for the HTTP server.
	Port() int

	// Cors applies CORS configuration to the Gin engine using functional options.
	Cors(opts ...func(*cors.Option))

	// Run boots the HTTP server, initializing modules and listening on the configured port.
	Run()
}

Runner is the application entrypoint interface for Solanum. It manages module initialization, global middlewares, CORS, and server start.

func NewSolanum

func NewSolanum(opts ...Option) Runner

NewSolanum creates and returns a new Runner configured with the given options.

type SolaController

type SolaController struct {
	// contains filtered or unexported fields
}

SolaController groups one or more SolaService handlers under a logical controller. It implements the Controller interface.

func NewController

func NewController() *SolaController

NewController constructs an empty SolaController ready to receive handlers.

func (*SolaController) Handlers

func (ctr *SolaController) Handlers() []*SolaService

Handlers returns the slice of SolaService entries managed by this controller.

func (*SolaController) SetHandlers

func (ctr *SolaController) SetHandlers(handlers ...*SolaService)

SetHandlers replaces the controller's handler list with the provided entries.

type SolaModule

type SolaModule struct {
	// contains filtered or unexported fields
}

SolaModule encapsulates a self-contained HTTP module with its own URI prefix, controllers, and middleware stacks.

func NewModule

func NewModule(opts ...moduleOption) *SolaModule

NewModule creates a new SolaModule with the given URI prefix. The module starts with empty controller and middleware lists.

func (*SolaModule) AddControllers

func (m *SolaModule) AddControllers(c ...Controller)

AddControllers appends one or more Controller implementations to this module.

func (*SolaModule) AddPostMiddleware added in v0.3.2

func (m *SolaModule) AddPostMiddleware(middleware gin.HandlerFunc)

AddPostMiddleware appends a single middleware to the post-handler chain.

func (*SolaModule) AddPreMiddleware added in v0.3.2

func (m *SolaModule) AddPreMiddleware(middleware gin.HandlerFunc)

AddPreMiddleware appends a single middleware to the pre-handler chain.

func (*SolaModule) Controllers

func (m *SolaModule) Controllers() []Controller

Controllers returns all controllers registered in this module.

func (*SolaModule) PostMiddlewares added in v0.3.0

func (m *SolaModule) PostMiddlewares() []gin.HandlerFunc

PostMiddlewares returns the list of middleware to execute after handlers.

func (*SolaModule) PreMiddlewares added in v0.3.0

func (m *SolaModule) PreMiddlewares() []gin.HandlerFunc

PreMiddlewares returns the list of middleware to execute before handlers.

func (*SolaModule) SetControllers

func (m *SolaModule) SetControllers(c ...Controller)

SetControllers registers one or more Controller implementations for this module.

func (*SolaModule) SetPostMiddlewares added in v0.4.0

func (m *SolaModule) SetPostMiddlewares(middlewares ...gin.HandlerFunc)

SetPostMiddlewares replaces the post-handler middleware chain with the provided list.

func (*SolaModule) SetPreMiddlewares added in v0.4.0

func (m *SolaModule) SetPreMiddlewares(middlewares ...gin.HandlerFunc)

SetPreMiddlewares replaces the pre-handler middleware chain with the provided list.

func (*SolaModule) SetRoutes

func (m *SolaModule) SetRoutes(router *gin.RouterGroup)

SetRoutes registers the module's routes and middleware on the given RouterGroup. The final handler chain per route is: module pre-middlewares → service PreHandlers → handler → service PostHandlers → module post-middlewares.

func (*SolaModule) Uri

func (m *SolaModule) Uri() string

Uri returns the base URI prefix for this module.

type SolaService

type SolaService struct {
	// Uri is the route path relative to the module prefix (e.g., "/:id").
	Uri string

	// Method is the HTTP method to bind (GET, POST, etc.).
	Method string

	// PreHandlers are middleware functions to run before Handler for this route only.
	PreHandlers []gin.HandlerFunc

	// Handler is the Gin handler function to execute.
	Handler gin.HandlerFunc

	// PostHandlers are middleware functions to run after Handler for this route only.
	// Gin executes all handlers in the chain sequentially; ctx.Next() is not required.
	// Use ctx.Abort() in any handler to stop further execution.
	PostHandlers []gin.HandlerFunc
}

SolaService represents a single HTTP route handler configuration.

Directories

Path Synopsis
docs
examples/simple command
middleware

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL