ramchi
is an extension to the go-chi HTTP router designed for rapid and modular development of REST APIs.
- Modular router and middleware loading system
- Feature flag support via experimental toggles for safe progressive rollout
- Easy-to-configure TLS/HTTPS support
- Graceful shutdown and OS signal handling for clean service termination
- Built-in, extensible helper packages for requests, responses, crypto, email, and more
- Automatic configuration file generation and hot loading
- Integrated structured logging powered by zerolog
- Toggle middleware globally via configuration, reducing boilerplate
Use Go Modules to install:
go get -u github.com/etwodev/ramchi
Below is a minimal example demonstrating how to create and start a ramchi
server with a modular router and endpoint registration.
package main
import (
"encoding/json"
"net/http"
"github.com/etwodev/ramchi"
"github.com/etwodev/ramchi/router"
)
func main() {
s := ramchi.New()
s.LoadRouter(Routers())
s.Start()
}
// Define routers with their prefixes and routes
func Routers() []router.Router {
return []router.Router{
router.NewRouter("example", Routes(), true, nil),
}
}
// Define individual routes for the router
func Routes() []router.Route {
return []router.Route{
router.NewGetRoute("/demo", true, false, ExampleGetHandler, nil),
}
}
// ExampleGetHandler handles GET /example/demo requests
func ExampleGetHandler(w http.ResponseWriter, r *http.Request) {
res, _ := json.Marshal(map[string]string{"success": "ping"})
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
if _, err := w.Write(res); err != nil {
// Handle write error (in production, use proper error logging)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
Note: On the first run,
ramchi
auto-generates a defaultramchi.config.json
file in your working directory, which you can customize as needed.
The behavior of the server and feature toggling is controlled by the ramchi.config.json
file.
{
"port": "7000",
"address": "0.0.0.0",
"experimental": false,
"logLevel": "info",
"enableTLS": false,
"tlsCertFile": "",
"tlsKeyFile": "",
"readTimeout": 15,
"writeTimeout": 15,
"idleTimeout": 60,
"maxHeaderBytes": 1048576,
"shutdownTimeout": 15,
"enableCORS": false,
"allowedOrigins": ["*"],
"enableRequestLogging": false
}
Field | Type | Description | Default |
---|---|---|---|
port |
string | TCP port the server listens on | "7000" |
address |
string | IP address to bind to | "0.0.0.0" |
experimental |
bool | Enables or disables experimental feature flags | false |
logLevel |
string | Log verbosity level (debug , info , warn , error , fatal , disabled ) |
"info" |
enableTLS |
bool | Enable HTTPS by providing TLS certificate and key | false |
tlsCertFile |
string | Path to TLS certificate file (required if enableTLS is true ) |
"" |
tlsKeyFile |
string | Path to TLS key file (required if enableTLS is true ) |
"" |
readTimeout |
int | Max seconds allowed to read incoming requests | 15 |
writeTimeout |
int | Max seconds allowed to write responses | 15 |
idleTimeout |
int | Max seconds to keep idle HTTP connections open | 60 |
maxHeaderBytes |
int | Maximum size in bytes for HTTP headers | 1048576 |
shutdownTimeout |
int | Timeout in seconds for graceful server shutdown | 15 |
enableCORS |
bool | Automatically enables Cross-Origin Resource Sharing (CORS) middleware | false |
allowedOrigins |
[]string | List of allowed origins for CORS (e.g., ["*"] , ["https://example.com"] ) |
["*"] |
enableRequestLogging |
bool | Enables HTTP request logging middleware globally | false |
Enable built-in middleware globally using config flags without manual registration:
Middleware | Config Flag | Description |
---|---|---|
CORS | enableCORS |
Adds permissive or restricted CORS headers |
Request Logging | enableRequestLogging |
Logs incoming HTTP requests with structured logs |
For fine-grained control (middleware order, conditional logic), register middleware manually using
LoadMiddleware()
.
You can access configuration values in your application via the config
package:
import c "github.com/etwodev/ramchi/v2/config"
port := c.Port() // e.g. "7000"
addr := c.Address() // e.g. "0.0.0.0"
if c.Experimental() {
// Enable or disable experimental features accordingly
}
if c.EnableTLS() {
cert := c.TLSCertFile()
key := c.TLSKeyFile()
// Use cert and key for HTTPS server setup
}
ramchi
integrates zerolog for structured, leveled logging:
- Log levels controlled via
logLevel
config (debug
,info
,warn
,error
,fatal
,disabled
) - Console-friendly output by default, but pluggable to other loggers if needed
- Logs contextual information: server name, HTTP method, route, middleware names, error stack traces
- Logs graceful shutdown steps, warnings, and fatal errors
- Organize routes modularly using
router.Router
instances grouped by prefixes. - Respect feature flags by setting the
Experimental
flag on routes/middleware. - Use middleware chaining to add cross-cutting concerns like authentication, CORS, logging.
- Use the status flag to disable routes/middleware temporarily without deleting code.
To serve over HTTPS:
- Set
"enableTLS": true
inramchi.config.json
. - Provide valid paths to
"tlsCertFile"
and"tlsKeyFile"
for your SSL certificate and private key. - Restart your server.
ramchi
will handle HTTPS setup automatically.
ramchi
includes utility helper packages to accelerate development:
Helper Package | Description |
---|---|
helpers/request.go |
Utilities for HTTP requests (client IP extraction, params) |
helpers/response.go |
JSON encoding, error handling, standardized responses |
helpers/crypto.go |
Cryptographic helpers: hashing, encryption utilities |
helpers/email.go |
Email templating and sending utilities |
helpers/strings.go |
String manipulation (padding, truncation, sanitization) |
helpers/encoding.go |
Encoding helpers (hex, base64 conversions) |
Feel free to extend or create your own helper packages and contribute back.
Contributions, feature requests, and bug reports are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature-name
) - Write tests for your changes
- Submit a Pull Request describing your improvements
- Open issues for discussion before implementing breaking changes
Here's an example of grouping multiple routers and adding middleware. Of course, in reality, you would put your routes in a separate package for brevity:
package main
import (
"net/http"
"github.com/example/project/middleware/logger"
"github.com/etwodev/ramchi"
"github.com/etwodev/ramchi/router"
)
func main() {
s := ramchi.New()
s.LoadMiddleware(Middlewares())
s.LoadRouter(Routers())
s.Start()
}
func Routers() []router.Router {
return []router.Router{
router.NewRouter("api/v1", apiV1Routes(), true, nil),
router.NewRouter("admin", adminRoutes(), true, nil),
}
}
func Middlewares() []middleware.Middleware {
return []middleware.Middleware{
middleware.NewMiddleware(logger.Middleware(), "logger", true, false),
}
}
func apiV1Routes() []router.Route {
return []router.Route{
router.NewGetRoute("/users", true, false, usersHandler, nil),
router.NewPostRoute("/users", true, false, createUserHandler, nil),
}
}
func adminRoutes() []router.Route {
return []router.Route{
router.NewGetRoute("/dashboard", true, false, adminDashboardHandler, nil),
}
}
For questions, discussions, or support, please open an issue.
MIT License © Etwodev