Loading documentation...
Loading documentation...
Loading documentation...
Note: This is a developer-maintained documentation page. The content here is not auto-generated and should be updated manually to explain the core concepts and architecture of the Helix package.
Import Path: github.com/kolosys/helix
Package helix provides a zero-dependency, context-aware, high-performance HTTP web framework for Go with stdlib compatibility.
Helix is built on Go's standard library (net/http) and provides a thin, high-performance layer on top. The architecture follows these principles:
sync.PoolHTTP Request
↓
Middleware Chain (RequestID, Logger, etc.)
↓
Router (matches route, extracts parameters)
↓
Handler (Ctx handler, typed handler, or http.HandlerFunc)
↓
Response (JSON, Problem, etc.)
↓
Middleware Chain (response processing)
↓
HTTP ResponseHelix provides two ways to create a server:
// Basic server (no middleware)
s := helix.New()
// Default server (includes RequestID, Logger, Recover)
s := helix.Default()Helix supports three handler styles:
#1. Standard Handler: Works with any http.HandlerFunc
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, data)
})#2. Ctx Handler: Uses Ctx for fluent API
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))#3. Typed Handler: Generic handlers with automatic binding
s.POST("/users", helix.Handle(func(ctx context.Context, req CreateRequest) (User, error) {
return userService.Create(ctx, req)
}))Bind request data using struct tags:
type CreateUserRequest struct {
ID int `path:"id"`
Name string `json:"name"`
Email string `json:"email"`
Page int `query:"page"`
}
req, err := helix.Bind[CreateUserRequest](r)Errors are automatically converted to RFC 7807 Problem responses:
s.GET("/users/{id}", helix.HandleCtx(func(c *helix.Ctx) error {
user, err := userService.Get(c.Context(), c.Param("id"))
if err != nil {
return helix.NotFoundf("user not found")
}
return c.OK(user)
}))Routes support path parameters, groups, modules, and resources:
// Path parameters
s.GET("/users/{id}", handler)
// Groups
api := s.Group("/api/v1")
api.GET("/users", handler)
// Modules
s.Mount("/users", &UserModule{})
// Resources
s.Resource("/users").CRUD(list, create, get, update, delete)Helix has zero external dependencies because:
Ctx and path parameters use sync.PoolHelix prioritizes:
http.Handler middlewarepackage main
import (
"github.com/kolosys/helix"
)
func main() {
s := helix.Default()
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, map[string]string{"message": "Hello, World!"})
})
s.Start(":8080")
}s := helix.Default()
api := s.Group("/api/v1")
// Users resource
api.Resource("/users").CRUD(
listUsers,
createUser,
getUser,
updateUser,
deleteUser,
)// users/module.go
type UserModule struct {
service *UserService
}
func (m *UserModule) Register(r helix.RouteRegistrar) {
r.GET("/", m.list)
r.POST("/", m.create)
r.GET("/{id}", m.get)
}
// main.go
s.Mount("/api/v1/users", &UserModule{service: userService})s := helix.New(
helix.WithAddr(":8080"),
helix.WithReadTimeout(30 * time.Second),
helix.WithWriteTimeout(30 * time.Second),
helix.WithGracePeriod(30 * time.Second),
)
// Production middleware
for _, mw := range middleware.Production() {
s.Use(mw)
}
s.OnStart(func(s *helix.Server) {
// Initialize services
})
s.OnStop(func(ctx context.Context, s *helix.Server) {
// Cleanup
})
s.Start()Problem: Handlers must return errors for proper response handling.
Solution: Always return errors (or nil):
// ❌ Wrong
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
c.OK(users) // Missing return
}))
// ✅ Correct
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))Problem: HTTP request bodies can only be read once.
Solution: Let binding handle the body:
// ❌ Wrong
body, _ := io.ReadAll(r.Body)
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Fails
// ✅ Correct
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Reads body automaticallyProblem: More specific routes must be registered before catch-all routes.
Solution: Register specific routes first:
// ❌ Wrong
s.GET("/files/{path...}", catchAll)
s.GET("/files/users", users) // Never matches
// ✅ Correct
s.GET("/files/users", users)
s.GET("/files/{path...}", catchAll)Helix is fully compatible with net/http:
// Use stdlib middleware
s.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your middleware
next.ServeHTTP(w, r)
})
})
// Use stdlib handlers
s.Handle("/legacy", legacyHandler)Helix can be integrated with other frameworks:
// Mount Helix server as sub-router
mux := http.NewServeMux()
helixServer := helix.Default()
mux.Handle("/api/", helixServer)Helix works with any database library:
// Using sql.DB
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
rows, err := db.QueryContext(c.Context(), "SELECT...")
// ...
}))
// Using gorm
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
var users []User
db.WithContext(c.Context()).Find(&users)
return c.OK(users)
}))This documentation should be updated by package maintainers to reflect the actual architecture and design patterns used.
Note: This is a developer-maintained documentation page. The content here is not auto-generated and should be updated manually to explain the core concepts and architecture of the Helix package.
Import Path: github.com/kolosys/helix
Package helix provides a zero-dependency, context-aware, high-performance HTTP web framework for Go with stdlib compatibility.
Helix is built on Go's standard library (net/http) and provides a thin, high-performance layer on top. The architecture follows these principles:
sync.PoolHTTP Request
↓
Middleware Chain (RequestID, Logger, etc.)
↓
Router (matches route, extracts parameters)
↓
Handler (Ctx handler, typed handler, or http.HandlerFunc)
↓
Response (JSON, Problem, etc.)
↓
Middleware Chain (response processing)
↓
HTTP ResponseHelix provides two ways to create a server:
// Basic server (no middleware)
s := helix.New()
// Default server (includes RequestID, Logger, Recover)
s := helix.Default()Helix supports three handler styles:
#1. Standard Handler: Works with any http.HandlerFunc
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, data)
})#2. Ctx Handler: Uses Ctx for fluent API
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))#3. Typed Handler: Generic handlers with automatic binding
s.POST("/users", helix.Handle(func(ctx context.Context, req CreateRequest) (User, error) {
return userService.Create(ctx, req)
}))Bind request data using struct tags:
type CreateUserRequest struct {
ID int `path:"id"`
Name string `json:"name"`
Email string `json:"email"`
Page int `query:"page"`
}
req, err := helix.Bind[CreateUserRequest](r)Errors are automatically converted to RFC 7807 Problem responses:
s.GET("/users/{id}", helix.HandleCtx(func(c *helix.Ctx) error {
user, err := userService.Get(c.Context(), c.Param("id"))
if err != nil {
return helix.NotFoundf("user not found")
}
return c.OK(user)
}))Routes support path parameters, groups, modules, and resources:
// Path parameters
s.GET("/users/{id}", handler)
// Groups
api := s.Group("/api/v1")
api.GET("/users", handler)
// Modules
s.Mount("/users", &UserModule{})
// Resources
s.Resource("/users").CRUD(list, create, get, update, delete)Helix has zero external dependencies because:
Ctx and path parameters use sync.PoolHelix prioritizes:
http.Handler middlewarepackage main
import (
"github.com/kolosys/helix"
)
func main() {
s := helix.Default()
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, map[string]string{"message": "Hello, World!"})
})
s.Start(":8080")
}s := helix.Default()
api := s.Group("/api/v1")
// Users resource
api.Resource("/users").CRUD(
listUsers,
createUser,
getUser,
updateUser,
deleteUser,
)// users/module.go
type UserModule struct {
service *UserService
}
func (m *UserModule) Register(r helix.RouteRegistrar) {
r.GET("/", m.list)
r.POST("/", m.create)
r.GET("/{id}", m.get)
}
// main.go
s.Mount("/api/v1/users", &UserModule{service: userService})s := helix.New(
helix.WithAddr(":8080"),
helix.WithReadTimeout(30 * time.Second),
helix.WithWriteTimeout(30 * time.Second),
helix.WithGracePeriod(30 * time.Second),
)
// Production middleware
for _, mw := range middleware.Production() {
s.Use(mw)
}
s.OnStart(func(s *helix.Server) {
// Initialize services
})
s.OnStop(func(ctx context.Context, s *helix.Server) {
// Cleanup
})
s.Start()Problem: Handlers must return errors for proper response handling.
Solution: Always return errors (or nil):
// ❌ Wrong
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
c.OK(users) // Missing return
}))
// ✅ Correct
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))Problem: HTTP request bodies can only be read once.
Solution: Let binding handle the body:
// ❌ Wrong
body, _ := io.ReadAll(r.Body)
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Fails
// ✅ Correct
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Reads body automaticallyProblem: More specific routes must be registered before catch-all routes.
Solution: Register specific routes first:
// ❌ Wrong
s.GET("/files/{path...}", catchAll)
s.GET("/files/users", users) // Never matches
// ✅ Correct
s.GET("/files/users", users)
s.GET("/files/{path...}", catchAll)Helix is fully compatible with net/http:
// Use stdlib middleware
s.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your middleware
next.ServeHTTP(w, r)
})
})
// Use stdlib handlers
s.Handle("/legacy", legacyHandler)Helix can be integrated with other frameworks:
// Mount Helix server as sub-router
mux := http.NewServeMux()
helixServer := helix.Default()
mux.Handle("/api/", helixServer)Helix works with any database library:
// Using sql.DB
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
rows, err := db.QueryContext(c.Context(), "SELECT...")
// ...
}))
// Using gorm
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
var users []User
db.WithContext(c.Context()).Find(&users)
return c.OK(users)
}))This documentation should be updated by package maintainers to reflect the actual architecture and design patterns used.
HTTP Request
↓
Middleware Chain (RequestID, Logger, etc.)
↓
Router (matches route, extracts parameters)
↓
Handler (Ctx handler, typed handler, or http.HandlerFunc)
↓
Response (JSON, Problem, etc.)
↓
Middleware Chain (response processing)
↓
HTTP Response// Basic server (no middleware)
s := helix.New()
// Default server (includes RequestID, Logger, Recover)
s := helix.Default()s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, data)
})s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))s.POST("/users", helix.Handle(func(ctx context.Context, req CreateRequest) (User, error) {
return userService.Create(ctx, req)
}))type CreateUserRequest struct {
ID int `path:"id"`
Name string `json:"name"`
Email string `json:"email"`
Page int `query:"page"`
}
req, err := helix.Bind[CreateUserRequest](r)s.GET("/users/{id}", helix.HandleCtx(func(c *helix.Ctx) error {
user, err := userService.Get(c.Context(), c.Param("id"))
if err != nil {
return helix.NotFoundf("user not found")
}
return c.OK(user)
}))// Path parameters
s.GET("/users/{id}", handler)
// Groups
api := s.Group("/api/v1")
api.GET("/users", handler)
// Modules
s.Mount("/users", &UserModule{})
// Resources
s.Resource("/users").CRUD(list, create, get, update, delete)package main
import (
"github.com/kolosys/helix"
)
func main() {
s := helix.Default()
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, map[string]string{"message": "Hello, World!"})
})
s.Start(":8080")
}s := helix.Default()
api := s.Group("/api/v1")
// Users resource
api.Resource("/users").CRUD(
listUsers,
createUser,
getUser,
updateUser,
deleteUser,
)// users/module.go
type UserModule struct {
service *UserService
}
func (m *UserModule) Register(r helix.RouteRegistrar) {
r.GET("/", m.list)
r.POST("/", m.create)
r.GET("/{id}", m.get)
}
// main.go
s.Mount("/api/v1/users", &UserModule{service: userService})s := helix.New(
helix.WithAddr(":8080"),
helix.WithReadTimeout(30 * time.Second),
helix.WithWriteTimeout(30 * time.Second),
helix.WithGracePeriod(30 * time.Second),
)
// Production middleware
for _, mw := range middleware.Production() {
s.Use(mw)
}
s.OnStart(func(s *helix.Server) {
// Initialize services
})
s.OnStop(func(ctx context.Context, s *helix.Server) {
// Cleanup
})
s.Start()// ❌ Wrong
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
c.OK(users) // Missing return
}))
// ✅ Correct
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))// ❌ Wrong
body, _ := io.ReadAll(r.Body)
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Fails
// ✅ Correct
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Reads body automatically// ❌ Wrong
s.GET("/files/{path...}", catchAll)
s.GET("/files/users", users) // Never matches
// ✅ Correct
s.GET("/files/users", users)
s.GET("/files/{path...}", catchAll)// Use stdlib middleware
s.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your middleware
next.ServeHTTP(w, r)
})
})
// Use stdlib handlers
s.Handle("/legacy", legacyHandler)// Mount Helix server as sub-router
mux := http.NewServeMux()
helixServer := helix.Default()
mux.Handle("/api/", helixServer)// Using sql.DB
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
rows, err := db.QueryContext(c.Context(), "SELECT...")
// ...
}))
// Using gorm
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
var users []User
db.WithContext(c.Context()).Find(&users)
return c.OK(users)
}))HTTP Request
↓
Middleware Chain (RequestID, Logger, etc.)
↓
Router (matches route, extracts parameters)
↓
Handler (Ctx handler, typed handler, or http.HandlerFunc)
↓
Response (JSON, Problem, etc.)
↓
Middleware Chain (response processing)
↓
HTTP Response// Basic server (no middleware)
s := helix.New()
// Default server (includes RequestID, Logger, Recover)
s := helix.Default()s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, data)
})s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))s.POST("/users", helix.Handle(func(ctx context.Context, req CreateRequest) (User, error) {
return userService.Create(ctx, req)
}))type CreateUserRequest struct {
ID int `path:"id"`
Name string `json:"name"`
Email string `json:"email"`
Page int `query:"page"`
}
req, err := helix.Bind[CreateUserRequest](r)s.GET("/users/{id}", helix.HandleCtx(func(c *helix.Ctx) error {
user, err := userService.Get(c.Context(), c.Param("id"))
if err != nil {
return helix.NotFoundf("user not found")
}
return c.OK(user)
}))// Path parameters
s.GET("/users/{id}", handler)
// Groups
api := s.Group("/api/v1")
api.GET("/users", handler)
// Modules
s.Mount("/users", &UserModule{})
// Resources
s.Resource("/users").CRUD(list, create, get, update, delete)package main
import (
"github.com/kolosys/helix"
)
func main() {
s := helix.Default()
s.GET("/", func(w http.ResponseWriter, r *http.Request) {
helix.OK(w, map[string]string{"message": "Hello, World!"})
})
s.Start(":8080")
}s := helix.Default()
api := s.Group("/api/v1")
// Users resource
api.Resource("/users").CRUD(
listUsers,
createUser,
getUser,
updateUser,
deleteUser,
)// users/module.go
type UserModule struct {
service *UserService
}
func (m *UserModule) Register(r helix.RouteRegistrar) {
r.GET("/", m.list)
r.POST("/", m.create)
r.GET("/{id}", m.get)
}
// main.go
s.Mount("/api/v1/users", &UserModule{service: userService})s := helix.New(
helix.WithAddr(":8080"),
helix.WithReadTimeout(30 * time.Second),
helix.WithWriteTimeout(30 * time.Second),
helix.WithGracePeriod(30 * time.Second),
)
// Production middleware
for _, mw := range middleware.Production() {
s.Use(mw)
}
s.OnStart(func(s *helix.Server) {
// Initialize services
})
s.OnStop(func(ctx context.Context, s *helix.Server) {
// Cleanup
})
s.Start()// ❌ Wrong
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
c.OK(users) // Missing return
}))
// ✅ Correct
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
return c.OK(users)
}))// ❌ Wrong
body, _ := io.ReadAll(r.Body)
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Fails
// ✅ Correct
var req CreateRequest
helix.BindJSON[CreateRequest](r) // Reads body automatically// ❌ Wrong
s.GET("/files/{path...}", catchAll)
s.GET("/files/users", users) // Never matches
// ✅ Correct
s.GET("/files/users", users)
s.GET("/files/{path...}", catchAll)// Use stdlib middleware
s.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your middleware
next.ServeHTTP(w, r)
})
})
// Use stdlib handlers
s.Handle("/legacy", legacyHandler)// Mount Helix server as sub-router
mux := http.NewServeMux()
helixServer := helix.Default()
mux.Handle("/api/", helixServer)// Using sql.DB
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
rows, err := db.QueryContext(c.Context(), "SELECT...")
// ...
}))
// Using gorm
s.GET("/users", helix.HandleCtx(func(c *helix.Ctx) error {
var users []User
db.WithContext(c.Context()).Find(&users)
return c.OK(users)
}))