App

Application Startup

Trace how a GoLazy application is constructed and started.

By Guillermo Alvarez - Published - Updated

Start from main

The executable entry point stays small:

func main() {
    if err := appinit.App().ListenAndServe(); err != nil {
        log.Fatal(err)
    }
}

App() returns a fully constructed application. ListenAndServe starts the HTTP server.

Construct the app

init/app.go calls lazyapp.New:

func App() *lazyapp.App {
    return lazyapp.New(lazyapp.Config{
        Name:    "sample_app",
        Drawer:  Draw,
        Public:  app.Public,
        Views:   app.Views,
        Context: Context,
        Helpers: lazyapp.Helpers{helpers.RegisterHelpers()},
    })
}

That call initializes the renderer, route scope, dispatcher, asset registry, helpers, and application context.

Initialize shared context

Context runs once during application construction:

func Context(ctx context.Context) context.Context {
    posts, err := postservice.New()
    if err != nil {
        panic(err)
    }

    return postservice.WithContext(ctx, posts)
}

Controllers resolve shared dependencies from this context during request-local construction.

Draw routes

The app passes a framework-created route scope to Draw:

func Draw(router *lazyroutes.Scope) {
    router.Get("/", home.New, (*home.HomeController).Index)
    router.Resources(postcontroller.New)
}

Draw only registers routes. It does not create the mux, dispatcher, public fallback, or server.

Choose the address

ListenAndServe reads ADDR, then PORT, then falls back to :3000:

ADDR=127.0.0.1:4000 ./sample-app
PORT=4000 ./sample-app

A numeric ADDR or PORT value is treated as a port. A full address is passed to the underlying server.

CONTROL_PLANE_ADDR activates the default control plane during ListenAndServe. If it matches the app address, probes are mounted into the app server. If it differs, GoLazy starts a second server for the control plane.