VOOZH about

URL: https://deepwiki.com/mathsgod/light/2.2-request-lifecycle

⇱ Request Lifecycle | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Request Lifecycle

This page documents the complete lifecycle of an HTTP request through the Light framework, from the moment it arrives at the server until a response is sent back to the client. The lifecycle involves several distinct phases: request reception, middleware processing, authentication/authorization, GraphQL query execution, and response generation.

For information about the authentication mechanisms themselves, see Authentication Architecture. For GraphQL API structure and resolvers, see GraphQL API. For the core App class configuration, see App Class Initialization.


Overview

The Light framework processes HTTP requests through a multi-layered pipeline built on PSR-7/PSR-15 standards. The Light\App class (src/App.php38-39) serves as both a PSR-15 middleware and request handler, orchestrating the entire request lifecycle. Requests flow through a Laminas Stratigility middleware pipeline before reaching the App for GraphQL execution.

Key Components:

  • Light\Server - HTTP server wrapping Laminas components
  • Light\App - Central request processor implementing MiddlewareInterface and RequestHandlerInterface
  • Auth\Service - JWT-based authentication service
  • GraphQL\GraphQL - Query execution engine
  • TheCodingMachine\GraphQLite\SchemaFactory - GraphQL schema generator

Sources: src/App.php1-941


Request Flow Architecture


Sources: src/App.php38-39 src/App.php500-537 src/App.php154-170 src/App.php567-579


Phase 1: Request Reception and Middleware Processing

Server Initialization

The request lifecycle begins when an HTTP request is received by Light\Server, which is instantiated in the App constructor:

new \Light\Server($this->container)

The server pipes the App instance as middleware into the pipeline:

$this->server->pipe($this)

Sources: src/App.php70-72

Middleware Entry Point: App::process()

The App::process() method (src/App.php500-537) serves as the PSR-15 middleware entry point. This method performs several critical preprocessing steps:

Step 1: OPTIONS Request Handling

CORS preflight requests are immediately terminated with an empty 200 response:


Step 2: Request Body Parsing

If the request body hasn't been parsed yet, it reads and decodes the JSON payload:


Step 3: File Upload Processing

The GraphQL upload middleware processes multipart file uploads according to the GraphQL multipart request specification:


Step 4: App Instance Attachment

The App instance is attached as a request attribute for potential downstream access:


Sources: src/App.php500-537


Phase 2: Authentication and Authorization Setup

Auth Service Creation

The authentication service is instantiated from the incoming request, which extracts JWT tokens from headers or cookies:


The Auth\Service class examines the request for authentication tokens in the following order:

  1. Authorization header (Bearer token)
  2. access_token cookie

Sources: src/App.php526-527

Schema Factory Configuration

The authentication service is registered with the GraphQL schema factory to enable field-level authorization:


This enables GraphQLite's @Logged and @Right annotations to enforce access control at the GraphQL field level.

Sources: src/App.php529-530

Dependency Injection Registration

Both the request and auth service are registered in the DI container for downstream resolution:


Sources: src/App.php533-534

Handler Delegation

After preprocessing, the request is delegated to the next handler in the pipeline:


In the Light framework's configuration, the next handler is the App::handle() method itself, since App implements RequestHandlerInterface.

Sources: src/App.php536


Phase 3: GraphQL Query Execution

Request Handler Entry: App::handle()

The App::handle() method (src/App.php154-170) serves as the PSR-15 request handler. It orchestrates query execution and response generation:


Sources: src/App.php154-170 src/App.php567-579

Query Execution: App::execute()

The App::execute() method (src/App.php567-579) performs the actual GraphQL query execution:

Step 1: File Upload Reprocessing

File uploads are processed again to ensure uploaded files are available during query execution:


Step 2: Query Extraction

The GraphQL query string and variables are extracted from the parsed request body:


Step 3: Schema Creation

The GraphQL schema is created from the schema factory, which uses reflection to scan controller classes for @Query and @Mutation annotations:


The schema factory was previously configured with authentication/authorization services in App::process().

Step 4: Query Execution

The webonyx/graphql-php library executes the query against the schema:


The execution process:

  1. Parses the GraphQL query string into an AST
  2. Validates the query against the schema
  3. Executes resolvers (controller methods) for each field
  4. Checks @Right permissions before each resolver invocation
  5. Returns an ExecutionResult object containing data and/or errors

Sources: src/App.php567-579


Phase 4: Response Generation

Result Serialization

The App::handle() method (src/App.php154-170) converts the ExecutionResult into a JSON response:

Development Mode Response

When Config.mode != "prod", debug information including stack traces is included:


Production Mode Response

In production, only the data and error messages (without traces) are returned:


The JSON_UNESCAPED_UNICODE flag ensures international characters are properly encoded.

Sources: src/App.php154-170

Error Handling

If an exception occurs during response serialization, it's caught and returned as a GraphQL error:


Sources: src/App.php165-169


Complete Request Flow Diagram


Sources: src/App.php38-39 src/App.php500-537 src/App.php154-170 src/App.php567-579


Special Route Handlers

In addition to the main GraphQL endpoint, the App configures several special routes in App::run() (src/App.php843-922):

File System Access Routes

Route: GET /fs/{protocol}/{path:.*}

Serves files from the MountManager filesystem with authentication:


Route: GET /drive/{index}/{path:.*}

Serves files from a specific Drive instance:


Sources: src/App.php850-875

Token Refresh Route

Route: POST /refresh_token

Exchanges a refresh token cookie for a new access token:


This route has a restricted cookie path (/refresh_token) to limit the scope of the refresh token.

Sources: src/App.php877-920


Development vs Production Behavior

The request lifecycle differs between development and production modes based on Config.mode:

AspectDevelopment ModeProduction Mode
Debug InformationIncluded via DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACEExcluded
Schema Caching15 second cache lifetimePermanent cache (0 lifetime)
Error Stack TracesFull stack traces in GraphQL errorsOnly error messages
GraphQL IntrospectionEnabled by defaultControlled by schema factory config

Sources: src/App.php106-119 src/App.php160-164


Summary

The complete request lifecycle can be summarized as:

  1. Reception: Light\Server receives PSR-7 HTTP request
  2. Middleware: Laminas\Stratigility pipeline routes to App::process()
  3. Preprocessing: Parse body, handle uploads, create Auth\Service
  4. Authorization Setup: Configure schema factory with auth services
  5. Execution: App::handle()App::execute()GraphQL::executeQuery()
  6. Resolution: Schema factory invokes controller methods with RBAC checks
  7. Serialization: Convert ExecutionResult to JsonResponse
  8. Response: Return PSR-7 response through middleware pipeline to client

Each phase maintains separation of concerns while leveraging PSR standards for interoperability. The dual implementation of MiddlewareInterface and RequestHandlerInterface by the App class allows it to serve as both a middleware processor and the terminal handler in the pipeline.

Sources: src/App.php1-941