Modules

In Velora, modules are the core building blocks of your application. Each module encapsulates a specific domain of functionality, including routes, services, middlewares, and dependencies. Velora's modular architecture ensures clean separation of concerns, easy testing, and scalability for large applications.

🧩 What is a Module?

A module is a Go struct implementing the Module interface. This interface requires:

  • Register(container *dig.Container, app *fiber.App) error — This method registers the module's routes, services, and dependencies.
  • Middlewares() []string — Returns middlewares that should be applied specifically to this module.

📂 Module File Structure (*.module.go)

Each module is typically defined in a file with the .module.go suffix. This file contains the module struct, its registration logic, services, controllers, and local middlewares.

package app

import (
    "github.com/gofiber/fiber/v2"
    "go.uber.org/dig"
    "gorm.io/gorm"
    velora "github.com/aryan-salemababdi/Velora/app"
)

type AppModule struct{}

func New() *AppModule { return &AppModule{} }

func (m *AppModule) Register(container *dig.Container, app *fiber.App) error {
    db := InitDB() // initialize database
    container.Provide(func() *gorm.DB { return db })
    container.Provide(NewService)
    container.Provide(NewController)
    return container.Invoke(func(ctrl *Controller) {
        ctrl.RegisterRoutes(app)
    })
}

func (m *AppModule) Middlewares() []string {
    return []string{"auth", "logging"} // local middlewares for this module
}

Important points about module files:

  • Register: Sets up services, controllers, dependencies, and registers routes with Fiber.
  • Middlewares: Returns an array of middleware names that are applied only to this module's routes.
  • Helps Velora detect unregistered modules automatically.
  • ❗ Important: Always define at least one middleware per module. Velora will throw an error if a module has no middlewares.

📦 Registering Modules in main.go

Every new module you create in Velora must be explicitly registered in main.go. This is essential because Velora needs to know about all modules in order to:

  • Apply the module-specific middlewares.
  • Register the module's routes to the Fiber app.
  • Provide its services and dependencies via the DI container.
  • Track registered modules and detect unregistered ones.

Failing to register a module in main.go will result in a warning when starting the application, showing which modules exist on disk but are not registered.

app := velora.New()
if err := app.RegisterModule("user", userModule); err != nil {
    log.Fatal(err)
}

🌱 Module Lifecycle

Each module goes through the following lifecycle:

  • Initialization: Setup services, DB connections, and dependencies inside Register.
  • Middleware registration: Middlewares from Middlewares() are applied automatically.
  • Routing: Routes implementing RouteRegisterer are registered on Fiber.
  • Dependency Injection: All module dependencies are provided via Dig container.

🛠️ Global vs Module Middlewares

Velora allows you to attach middlewares globally or per-module:

  • Global Middleware: Applied to all routes via UseGlobalMiddleware.
  • Module Middleware: Only applied to this module's routes, returned by Middlewares().

🔍 Module Watching

Velora can monitor your project directory for unregistered modules using WatchModules. This ensures all modules are properly registered and prevents runtime errors.

app.WatchModules("./modules", time.Second*2) // checks every 2 seconds

🚀 Summary

Modules in Velora are the main way to structure applications. They provide:

  • Encapsulation of routes, services, and logic.
  • Automatic middleware management.
  • Integration with dependency injection container.
  • Easy detection of unregistered modules.
  • Scalability and maintainability for large applications.

Next, explore Routing to learn how to define endpoints and connect them with modules.