How bootstrap.StartUp() Initializes the Gorig Application: A Complete Code Walkthrough

The bootstrap.StartUp() function orchestrates the entire Gorig application initialization by registering the HTTP service, dumping router information, launching the server in a background goroutine, and managing graceful shutdown.

The jom-io/gorig repository provides a modular Go framework for building HTTP services with Gin. At the heart of every Gorig application lies the bootstrap.StartUp() function, which serves as the unified entry point that wires together configuration, service lifecycle management, and the web server. Understanding this initialization flow is essential for developers extending or debugging Gorig-based services.

Entry Point: Calling bootstrap.StartUp()

The simplest Gorig application requires only a single function call. The example binary at simple/main.go demonstrates the minimal setup:

package main

import "github.com/jom-io/gorig/bootstrap"

func main() {
    // Boots the full application (service registration, HTTP server, graceful shutdown)
    bootstrap.StartUp()
}

This entry point delegates all initialization complexity to the bootstrap package, allowing developers to focus on business logic rather than boilerplate server setup.

Service Registration Flow

Inside bootstrap/startup.go, the StartUp() function begins by invoking regWebService() to register the HTTP service with the global service registry. This function constructs a serv.Service struct that defines the lifecycle callbacks and configuration for the web server.

The registration process stores the service in a global map gServices defined in serv/serv.go. The registry rejects duplicate service codes, ensuring only a single HTTP instance can exist per application.

HTTP Service Configuration

The regWebService() function configures the HTTP service with specific parameters extracted from the application configuration:

Field Implementation Detail
Code "HTTP" (unique service identifier)
PORT configure.GetString("api.rest.addr", ":9617") (configurable, defaults to port 9617)
Startup httpx.Startup (creates the http.Server and Gin engine)
Shutdown httpx.Shutdown (gracefully stops the server with timeout)

This configuration separates concerns between the bootstrap orchestrator and the HTTP implementation details.

Router Inspection and Logging

After service registration, bootstrap.StartUp() calls httpx.DumpRouters() to enumerate all registered Gin routes. This includes the default GET /ping endpoint added during httpx package initialization, providing visibility into the available API surface before the server accepts traffic.

Starting the Server

The final initialization step invokes serv.Running(), which iterates over the gServices map and executes each service's Startup function. For the HTTP service, this triggers httpx.Startup in httpx/serv.go.

The httpx.Startup function performs the following:

  1. Singleton Guard: Returns early if gHttpServer already exists to prevent duplicate server instances.
  2. Server Configuration: Creates an http.Server wrapping the global Gin engine (gEngine) with configurable timeouts.
  3. Background Execution: Launches ListenAndServe in a separate goroutine, allowing serv.Running() to continue monitoring for shutdown signals.
  4. Error Handling: Fatal exit if the server fails to start (port conflicts, permission issues).

The Gin engine itself is prepared in httpx.init(), which attaches recovery middleware, logging, CORS, gzip compression, and the default health check endpoint.

Graceful Shutdown Mechanism

serv.Running() blocks on an OS interrupt signal (SIGINT, SIGTERM). Upon receiving the signal, it:

  1. Logs a shutdown banner.
  2. Creates a 5-second context deadline.
  3. Invokes each service's Shutdown function sequentially.

For the HTTP service, httpx.Shutdown calls http.Server.Shutdown() with the timeout context, allowing active connections to complete while rejecting new requests. This prevents abrupt connection drops and ensures data integrity during deployment or scaling events.

Summary

  • bootstrap.StartUp() serves as the unified entry point that orchestrates the entire Gorig application lifecycle.
  • The function registers the HTTP service via regWebService(), which configures the server port, startup, and shutdown callbacks in serv/serv.go.
  • Router information is dumped via httpx.DumpRouters() to provide visibility into available endpoints.
  • serv.Running() launches the HTTP server in a background goroutine through httpx.Startup, which wraps the Gin engine in a standard http.Server.
  • The application blocks until an OS signal triggers graceful shutdown via httpx.Shutdown, ensuring clean connection termination with a 5-second timeout.

Frequently Asked Questions

How do I customize the HTTP port in a Gorig application?

The port is configured via the api.rest.addr configuration key, which defaults to :9617 if not specified. You can set this in your configuration file or environment variables, and regWebService() will automatically pick it up when constructing the service struct in bootstrap/startup.go.

Can I register additional services alongside the HTTP service?

Yes. While bootstrap.StartUp() currently focuses on HTTP, the serv package in serv/serv.go supports multiple service registrations through serv.RegisterService(). You can extend the bootstrap flow to register custom services (databases, message queues, etc.) before calling serv.Running(), and the graceful shutdown mechanism will handle each service's Shutdown callback sequentially.

What happens if the HTTP server fails to start?

If httpx.Startup encounters an error (such as a port conflict or permission denied), it logs the error and triggers an immediate fatal exit. This prevents the application from running in a partially initialized state. The error originates from the standard library's http.Server.ListenAndServe() call within the goroutine spawned by httpx.Startup in httpx/serv.go.

How does Gorig handle concurrent requests during shutdown?

When an OS interrupt signal is received, serv.Running() creates a 5-second context deadline and passes it to httpx.Shutdown. This calls http.Server.Shutdown(ctx), which gracefully closes the listener and waits for existing connections to complete while rejecting new ones. If connections exceed the 5-second timeout, they are forcibly closed to ensure the process exits.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →