v0.21

request lifecycle

introduction

understanding how requests flow through dframework is critical for building predictable applications. the framework operates as a closed loop. every incoming http request is intercepted parsed and routed internally by the framework engine. you do not need to configure external web servers for basic request handling during development.

lifecycle overview

when a request enters the application it first hits the central application handler. the framework immediately determines if the application is running in a production environment with caching enabled.

the fast path

if the fast path is active the request bypasses several initialization steps and jumps directly into the pre compiled routing tables stored in compiled .rc files. this aggressive optimization drastically reduces latency for static routes and cached responses. the framework generates these highly optimized files during the production build step.

1// internal framework code demonstrating the fast path execution
2if (matchedStatic && matchedStatic._compiled) {
3 request.params = {};
4
5 // instantly execute the compiled .rc handler
6 const result = RequestContext.run(request, () =>
7 matchedStatic._compiled(request, response, this, this.router)
8 );
9 return this._routeResult(result, req, res);
10}

the request pipeline

if the fast path is not applicable the request enters the request pipeline. the pipeline is a specialized component that evaluates the request against internal stages before it ever reaches your application logic. it first checks if the request is asking for internal assets like the debug bar or the shield security scripts. if a match is found the pipeline serves the asset directly from memory.

static files and assets

next the pipeline evaluates static files. if static file serving is enabled the pipeline checks the public directory. if a valid file exists it streams the file back to the client with the appropriate caching headers. if the request does not match any static files the pipeline hands control over to the application router.

NOTE

during local development the internal server acts as a fully capable static file server. in production it is recommended to let nginx or a cdn handle static assets.

routing and middleware

the router is the core decision making engine. it receives the raw request wraps it in a managed request context and matches the url against your defined routes.

once a route is matched the router begins processing middleware. middleware forms an execution chain that the request must pass through. if any middleware aborts or returns a response the chain halts immediately and the response is sent back to the client.

dispatching to controllers

finally if all middleware passes the request reaches your designated controller. controllers in the framework are simple classes defining async methods. arguments like the request and response are optional making your business logic extremely clean. the result is then transformed into a managed response object which is ultimately flushed back to the client completing the lifecycle.

1// controllers/UserController.js
2export default class UserController {
3 async show(req) {
4 const user = await User.find(req.params.id);
5
6 // the json response is flushed directly back to the client
7 return json({ user });
8 }
9}