# Request context
Ts.ED provides an util to get request, response, to store and share data along all middlewares/endpoints during a request with . This context is created by Ts.ED when the request is handled by the server.
It contains some information as following:
- The request and response abstraction layer with and (since v5.64.0+),
- The request id,
- The request container used by the Ts.ED DI. It contains all services annotated with
@Scope(ProviderScope.REQUEST)
, - The current context resolved by Ts.ED during the request,
- The data returned by the previous endpoint if you use multiple handlers on the same route. By default data is empty.
- The to log some information related to the request and his id.
Here is an example:
import {Context, Controller, Get, Middleware, UseBefore} from "@tsed/common";
import {Forbidden} from "@tsed/exceptions";
import {AuthToken} from "../domain/auth/AuthToken";
@Middleware()
class AuthTokenMiddleware {
use(@Context() ctx: Context) {
if (!ctx.has("auth")) {
ctx.set("auth", new AuthToken(ctx.request));
}
try {
ctx.get("auth").claims(); // check token
} catch (er) {
throw new Forbidden("Access forbidden - Bad token");
}
}
}
@Controller("/")
@UseBefore(AuthTokenMiddleware) // protect all routes for this controller
class MyCtrl {
@Get("/")
get(@Context() context: Context, @Context("auth") auth: AuthToken) {
context.logger.info({event: "auth", auth}); // Attach log to the request
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
TIP
is attached to the context ctx.logger
. The RequestLogger stores all logs and Ts.ED prints (flushes) all logs after the response is sent by the server.
The approach optimizes performance by first sending in the response and then printing all logs.
# Endpoint metadata
is the current controller method executed by the request. Middleware can access to this endpoint metadata when you use the middleware over a controller method. By accessing to the you are able to:
- Get endpoint information,
- Create custom middleware and decorator,
- Get the controller class name and propertyKey.
import {StoreSet} from "@tsed/core";
import {Get, Controller, Middleware, Context, EndpointInfo, Use, Returns} from "@tsed/common";
import {Resource} from "./Resource"
@Middleware()
export class MyMiddleware {
use(@EndpointInfo() endpoint: EndpointInfo, @Context() ctx: Context) {
console.log(endpoint === ctx.endpoint) // true
console.log(ctx.endpoint.targetName) // MyCtrl
console.log(ctx.endpoint.propertyKey) // getMethod
console.log(ctx.endpoint.type) // Resource
console.log(ctx.endpoint.store.get('options')) // options
}
}
@Controller('/resources')
class MyCtrl {
@Get('/:id')
@Use(MyMiddleware)
@Returns(200, Resource)
@StoreSet('options', "options")
getMethod(): Resource {
return new Resource()
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Request and Response abstraction
provide a and classes which are an abstraction layer of the targeted platform (Express.js, Koa.js, etc...).
By using the PlatformContext interface, your code will be compatible with any platform. But, the abstraction doesn't or cannot provide all necessaries properties or methods. It's also possible to get the original request or response by different ways.
import {Middleware, Context, Req, Res} from "@tsed/common";
@Middleware()
export class MyMiddleware {
use(@Req() req: Req, @Res() res: Res, @Context() ctx: Context) {
// abstraction
console.log(ctx.request) // PlatformRequest
console.log(ctx.response) // PlatformResponse
// by decorator
console.log(req) // Express.Request
console.log(res) // Express.Response
// by
console.log(ctx.request.raw) // Express.Request
console.log(ctx.response.raw) // Express.Request
// by method
console.log(ctx.getRequest<Express.Request>()) // Express.Request
console.log(ctx.getResponse<Express.Response>()) // Express.Response
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# PlatformRequest
provide high level methods and properties to get request information. His interface is the following:
class PlatformRequest<T = Req> {
raw: T;
get url(): string;
get headers(): IncomingHttpHeaders;
get method(): string;
get body(): {[key: string]: any};
get cookies(): {[key: string]: any};
get params(): {[key: string]: any};
get query(): {[key: string]: any};
get session(): {[key: string]: any} | undefined;
get(name: string): string | undefined; // get header
accepts(mime?: string | string[]): string | string[] | false;
}
2
3
4
5
6
7
8
9
10
11
12
13
# PlatformResponse
provide high level methods like .body()
to send any data to your consumer.
This method can get Boolean
, Number
, String
, Date
, Object
, Array
or Stream
as input type and
determine the correct way to send the response to your consumer.
His interface is the following:
class PlatformResponse {
raw: Res;
get statusCode(): number;
get locals(): Record<string, any>;
status(status: number): this;
setHeaders(headers: {
[key: string]: any;
}): this;
contentType(contentType: string): this;
redirect(status: number, url: string): this;
location(location: string): this;
stream(data: ReadableStream | any): this;
render(path: string, options?: any): Promise<string>;
body(data: any): this;
onEnd(cb: Function): void;
destroy(): void;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Example:
import {Middleware, Context} from "@tsed/common";
@Middleware()
export class MyMiddleware {
use(@Context() ctx: Context) {
// set headers, content-type and status
ctx.setHeaders({"x-header": "header"});
ctx.contentType("application/json");
ctx.status(201);
// equivalent to ctx.response.raw.send()
ctx.body(null);
ctx.body(undefined);
ctx.body(true);
ctx.body(false);
// equivalent to ctx.response.raw.json()
ctx.body({});
ctx.body([]);
ctx.body(new Date());
// equivalent to readableStream.pipe(ctx.response.raw)
ctx.body(readableStream);
// use raw response
ctx
.getResponse<Express.Response>()
.status(201)
.send("Hello")
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- Session & cookies
- Passport.js
- TypeORM
- Mongoose
- GraphQL
- Socket.io
- Swagger
- AJV
- Multer
- Serve static files
- Templating
- Throw HTTP Exceptions
- Customize 404
- AWS
- Jest
- Seq
- Controllers
- Providers
- Model
- Converters
- Middlewares
- Pipes
- Interceptors
- Authentication
- Hooks
- Injection scopes
- Custom providers
- Custom endpoint decorator
- Testing