An HTTP service often needs its database before accepting requests and must keep
that database open until requests finish. The application package coordinates
these dependencies across startup, running work, and shutdown. It does not
construct dependencies for you or make them available through a lookup container.
Choose Coordination
Use an application when several components need one startup order, one owner for cleanup, or shared supervision. If your existing host already manages those responsibilities, keep using it: Arkoren’s router, server, and service packages work independently. You can run an HTTP server directly or adopt individual packages without adding an application.
To create an idle coordinator, import arkoren.dev/core/application:
app := application.New(func(app *application.Builder) {
app.Name("inventory")
})
This resolves construction settings but starts no resources or listeners. Choose component settings when constructing the application; its builder is not a runtime control handle.
Understand Phases
A composer is the temporary scope passed to your composition callback. Composition constructs concrete dependencies, passes typed values to their consumers, and registers work. Every composition callback finishes synchronously, in argument order, before any startup callback runs.
Inside composition, Startup registers initialization, Run registers supervised
running work, and Cleanup registers resource release. These calls register
callbacks; they do not execute them. Startup callbacks run in registration order.
Only after all succeed do runners and background health checks launch. A
constructed dependency is therefore not necessarily connected or ready to use.
Application Run combines startup, waiting for runners or caller cancellation,
and shutdown. Shutdown cancels runners, waits within its budget, then releases
resources in reverse cleanup-registration order. Register cleanup immediately
when ownership begins: it also runs if later construction or startup fails,
including for components whose startup never ran.
Composition shows how to construct and share typed values. Lifecycle and Ownership explains rollback, supervision, and cooperative shutdown. A successful startup does not establish continuing availability; Health and Readiness keeps that separate from lifecycle state.
Share Handles
Services that need logging, telemetry, or events receive those specific handles, not the application. At the top of a composition callback, bind only the handles it uses, then pass them to constructors. The handles are stable: a logger obtained before capture is attached still reaches that capture after startup. Keep the composer out of request handlers and background goroutines. Its context belongs to startup; runners use their supplied context instead.
The logger adds trace and span IDs from a valid context even before startup;
use context-aware methods such as InfoContext. Correlation does not enable
recording. Application telemetry records nothing without an explicit
telemetry configuration or
diagnostic capture. Recording starts after
composition, and telemetry finalizes after resource cleanup and final lifecycle
events. The application owns that lifecycle.
Choose Handler Exposure
If the service needs a temporary public home page, mount the welcome handler on
your existing routes *router.Router (arkoren.dev/core/http/router):
routes.Get("/", app.WelcomeHandler(), application.WelcomeOperation)
The exact-root route serves self-contained HTML containing the escaped application name and Arkoren resource links. Choose a name suitable for public display; an empty name uses a generic heading. It fetches no external assets, needs no JavaScript, and exposes no runtime, configuration, or build details. Replace it when you add your own home page; it is not a health probe. For a first request through a running service, follow the quickstart.
Operator information is different: InfoHandler exposes name, version,
environment, lifecycle state, log level, start time, uptime, and binary build
details. Restrict network access or add authentication and authorization before
mounting it. On an existing operator-only router:
operatorRoutes.Get(application.InfoPath, app.InfoHandler(), application.InfoOperation)
app.Info() returns the same snapshot inside the process. Neither handler is
mounted automatically or controlled by debug mode. Operation annotations document
the registered routes; they do not protect them. Follow
diagnostic endpoint protection before remote
exposure, and use dedicated probes for
traffic and restart decisions.
Focused fragments in these guides keep error results visible but omit routine propagation. Checks that determine ownership or another consequential decision remain explicit; complete application code must handle its errors.
For construction and runtime contracts, see the
application API reference.