Switch engines. Keep your handlers. Ship fast.
cenery wraps popular Go web frameworks behind one clean API, so you can move between Echo, Fiber (v2/v3), Gin, Chi, and fasthttp without rewriting your app.
- One handler interface across engines
- Same middleware flow, different runtime
- Built-in helpers: JSON, streams, file uploads
go get github.com/dreamph/cenerypackage main
import (
"log"
"github.com/dreamph/cenery"
echoengine "github.com/dreamph/cenery/engine/echo"
)
func main() {
app := cenery.NewServer(echoengine.NewApp())
app.Get("/", func(c cenery.Ctx) error {
return c.SendString(200, "hello")
})
if err := app.Listen(":2000"); err != nil {
log.Fatal(err)
}
}Import paths:
- Fiber v2:
github.com/dreamph/cenery/engine/fiber - Fiber v3:
github.com/dreamph/cenery/engine/fiber3
// Echo
app := cenery.NewServer(echoengine.NewApp())
// Fiber
app := cenery.NewServer(fiberengine.NewApp())
// Fiber v3
app := cenery.NewServer(fiber3engine.NewApp())
// Gin
app := cenery.NewServer(ginengine.NewApp())
// Chi
app := cenery.NewServer(chiengine.NewApp())
// fasthttp
app := cenery.NewServer(fasthttpengine.NewApp())// Echo
echoApp := echo.New()
echoApp.Use(echomiddleware.Recover())
app := cenery.NewServer(echoengine.New(echoApp))
// Fiber
fiberApp := fiber.New(fiber.Config{
JSONDecoder: gojson.Unmarshal,
JSONEncoder: gojson.Marshal,
})
fiberApp.Use(fiberrecover.New())
app := cenery.NewServer(fiberengine.New(fiberApp))
// Fiber v3
fiber3App := fiber3.New(fiber3.Config{
JSONDecoder: gojson.Unmarshal,
JSONEncoder: gojson.Marshal,
})
fiber3App.Use(fiber3recover.New())
app := cenery.NewServer(fiber3engine.New(fiber3App))
// Gin
ginApp := gin.New()
ginApp.Use(gin.Recovery())
app := cenery.NewServer(ginengine.New(ginApp))
// Chi
chiApp := chi.NewRouter()
chiApp.Use(middleware.Recoverer)
app := cenery.NewServer(chiengine.New(chiApp))
// fasthttp
routerApp := router.New()
app := cenery.NewServer(fasthttpengine.New(routerApp))app.Post("/upload", func(c cenery.Ctx) error {
file := c.FormFile("file")
if file == nil {
return c.SendJSON(400, map[string]string{"error": "missing file"})
}
return c.SendJSON(200, map[string]any{
"name": file.FileName,
"size": file.FileSize,
})
})
app.Get("/stream", func(c cenery.Ctx) error {
reader := strings.NewReader("streaming data")
return c.SendStream(200, "text/plain", reader)
})cenery accepts :id style and maps it for engines like Chi/fasthttp.
app.Get("/users/:id", func(c cenery.Ctx) error {
id := c.Params("id")
return c.SendString(200, "id="+id)
})app.Use(func(c cenery.Ctx) error {
start := time.Now()
err := c.Next()
elapsed := time.Since(start)
log.Printf("method=%s path=%s status=%d in=%s",
c.Request().GetHeader("Method"),
c.Request().GetHeader("Path"),
c.Response().GetHeader("Status"),
elapsed,
)
return err
})Try these:
test/main.gotest/cenery/echo/main.gotest/cenery/fiber/main.gotest/cenery/fiber3/main.gotest/cenery/gin/main.gotest/cenery/chi/main.gotest/cenery/fasthttp/main.go
MIT