Skip to content

H3ravel Request Lifecycle

The request lifecycle in H3ravel is structured, modular, and highly extensible. Here’s how a request flows through the system from server startup to response dispatch.

App Bootstrap (src/server.ts & src/bootstrap/app.ts)

This is the entry point of the application.

ts
new app().bootstrap();

Within bootstrap():

ts
const app = new Application(process.cwd());
  • Creates the core Application container instance (inherits from Container)
  • Registers all configured service providers
  • Boots each service provider
  • Creates an h3App (the internal H3 handler instance)
  • Sets up the Kernel, injects middleware (like LogRequests)
  • Starts listening via serve() on port 3000 (default) or your custom defined port

At this point, your app is ready to receive requests.

Application Container Initialization

Next the service container bindings are registered in the Application class constructor:

ts
this.registerBaseBindings();

This will bind the core services like:

  • Application: The application itself
  • path.base: The application base path
  • load.paths: Mappings of all other application paths

Then loads .env variables using dotenv.

The container now holds environment and path info required by providers and the app itself.

Service Provider Registration and Booting

The lifecycle proceeds to load all internal and external service providers, sorts them based on priority or order, calls each provider’s register() method and then calls each provider’s boot() method (if present).

Services such as config, view (Edge), and HTTP are registered here.

H3 Integration and Kernel Setup

ts
const kernel = new Kernel(
  (event) =>
    HttpContext.init({
      app,
      request: new Request(event, app),
      response: new Response(event, app),
    }),
  [new LogRequests()]
);

Each incoming H3Event is wrapped into a custom HttpContext exposing the following for subsequent use:

  • request: The H3ravel Request class
  • response: The H3ravel Response class
  • app: The H3ravel service container

H3 hands the event off to Kernel.handle().

Kernel Handling

The Kernel.handle() method converts H3Event into the HttpContext, dynamically binds the view renderer (Edge) to the container:

ts
const ctx = this.context(event);

app.bind('view', () => async (template, params) => {
  const edge = app.make('edge');
  return ctx.response.html(await edge.render(template, params));
});

Next it executes all middleware in sequence, if the result is a plain object, the required JSON headers will be set automatically:

Middleware Execution

The runMiddleware() method runs all middleware classes in order.

Each middleware must implement the IMiddleware contract interface, if no middleware interrupts, the final handler (next) is invoked.

Controller or Final Handler

At this point, the final handler which could be a controller or a callback is executed and the response is finalized and sent to the client.

Lifecycle Summary

StageDescription
bootstrap()Starts app, registers providers, sets up H3
ApplicationHolds the container, manages paths & env
Service ProvidersRegister & boot services into the container
KernelHandles request context, runs middleware, final handler
HttpContextUnified object for request/response/app
MiddlewareOptional processors before final handler
View/ResponseResponse generated by controller or handler

Released under the MIT License.