Custom Binary Embedding (pkg/app)
Embed the complete Moul engine in your Go binary, add custom HTTP routes, and register worker handlers.
pkg/app allows embedding the complete moul server into custom Go binaries with tailored HTTP endpoints, custom middleware, and Go worker handlers.
Complete Custom Binary Example
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/labstack/echo/v5"
"github.com/moul-dev/moul-dev/internal/worker"
"github.com/moul-dev/moul-dev/pkg/app"
)
func main() {
// 1. Instantiate engine
moulApp := app.New(app.Config{
Version: "1.0.0-custom",
})
// 2. Register custom HTTP route
moulApp.RegisterRoute("GET", "/api/custom/ping", func(c *echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{
"status": "pong",
"server": "custom-moul",
})
})
// 3. Attach directly to raw Echo router
moulApp.OnRouterInit(func(router *echo.Echo) error {
router.GET("/api/custom/health", func(c *echo.Context) error {
return c.String(http.StatusOK, "Engine healthy")
})
return nil
})
// 4. Register custom background job handler
moulApp.RegisterWorker("ProcessThumbnail", func(ctx context.Context, job *worker.Job) error {
imageURL, ok := job.Args["image_url"].(string)
if !ok {
return fmt.Errorf("missing image_url")
}
fmt.Printf("Processing thumbnail for: %s\n", imageURL)
// Process image logic...
return nil
})
// 5. Register periodic cron worker
moulApp.RegisterPeriodicWorker(24*time.Hour, "DailyReport", func(ctx context.Context, job *worker.Job) error {
fmt.Println("Running daily report cleanup...")
return nil
})
// 6. Start the server (blocks until SIGINT / SIGTERM)
if err := moulApp.Start(context.Background()); err != nil {
panic(err)
}
}Extension Hooks Reference
RegisterRoute(method, path, handler)
Registers a single HTTP handler on the embedded router before server start.
OnRouterInit(callback)
Provides access to the underlying *echo.Echo instance, enabling custom middleware registration, grouping, and advanced route configurations.
OnBeforeStart(callback)
Fires after SQLite database connections and dynamic collections are initialized, but before HTTP listening begins. Ideal for running custom migrations or seeding initial collection fixtures.