-
Notifications
You must be signed in to change notification settings - Fork 0
Core Concepts
@nextrush/core gives you three pieces: an application instance (middleware + routes + plugins), a context (ctx) per request, and middleware composition with await next().
For request lifecycle detail, see Request lifecycle on the docs site.
createApp() returns an Application: register middleware, mount routers, attach plugins, set a global error handler, then start listening.
import { createApp, listen } from 'nextrush';
const app = createApp({
env: 'production',
proxy: false,
logger: undefined,
});app.use(async (ctx, next) => {
ctx.state.startedAt = Date.now();
await next();
});
// Then packages such as @nextrush/cors, @nextrush/helmet, @nextrush/body-parser — see Middleware wiki pageconst users = createRouter();
users.get('/', listUsers);
app.route('/api/users', users);app.plugin(loggerPlugin({ level: 'info' }));
await app.plugin(databasePlugin({ uri: process.env.DATABASE_URL! }));import { ValidationError } from '@nextrush/errors';
app.setErrorHandler((error, ctx) => {
if (error instanceof ValidationError) {
ctx.status = 400;
ctx.json({ error: error.message });
return;
}
ctx.status = 500;
ctx.json({ error: 'Internal Server Error' });
});After listen() resolves, configuration is frozen: no more use(), route(), or plugin() on that instance. Use app.close() for graceful shutdown (plugins tear down in reverse order).
One object carries request fields and helpers to send a response.
Input
| Member | Role |
|---|---|
method, path
|
Verb and path |
params |
Route params (:id, wildcards) |
query |
Query string |
body |
Parsed body (after body-parser middleware) |
headers |
Raw header map |
get(name) |
Single header (case-insensitive) |
state |
Mutable bag for middleware |
Output
| Method / field | Role |
|---|---|
status |
HTTP status |
json(data), send(), html()
|
Body helpers |
redirect(url, code?) |
Redirect |
set(name, value) |
Response header |
Chain
| API | Role |
|---|---|
await ctx.next() |
Enter the rest of the stack |
(ctx, next) => … |
Same as await next()
|
Middleware runs in an onion: code before next() runs outward-to-in; code after next() runs on the way back.
flowchart LR
subgraph inbound["Toward handler"]
M1["A: before"]
M2["B: before"]
H["Handler"]
end
subgraph outbound["Toward response"]
M2b["B: after"]
M1b["A: after"]
end
M1 --> M2 --> H
H --> M2b --> M1b
Short-circuit by not calling next() after you set status and body (for example auth failure).
Share data with ctx.state so downstream middleware and handlers see the same object.
A plugin implements Plugin: usually install(app) registers middleware or hooks.
import type { Plugin, Application } from 'nextrush';
const myPlugin: Plugin = {
name: 'my-plugin',
install(app: Application) {
app.use(/* … */);
},
};
app.plugin(myPlugin);PluginWithHooks adds optional extendContext, onRequest, onResponse, onError, and destroy for instrumentation or cleanup.
Use app.hasPlugin('name') / app.getPlugin('name') when another plugin needs to detect optional peers.
- Middleware — packaged middleware and ordering
- Routing — router API
- Plugins concept — docs site
NextRush · MIT License · Docs · Issues