# Interceptors
An interceptor is a class annotated with the Interceptor decorator. Interceptors should implement the InterceptorMethods interface.
Interceptors have a set of useful capabilities which are inspired by the Aspect Oriented Programming (opens new window) (AOP) technique.
Creating and consuming an interceptor is a two-step process:
- Create and annotate the interceptor class that will intercept calls to service methods
- Decide which methods will be intercepted by which interceptor
They make it possible to:
- bind extra logic before / after method execution
- transform the result returned from a function
- transform the exception thrown from a function
- extend the basic function behavior
- completely override a function depending on specific conditions
# Decorators
# Interceptor class
To create an interceptor class you need to implement the IInterceptor
interface and implement the
intercept(context: IInterceptorContext<any>, next?: IInterceptorNextHandler)
method, and use the @Interceptor()
annotation to register your interceptor class.
Inside your src/interceptors/MyInterceptor.ts
folder, create the following simple interceptor.
import {InterceptorMethods, InterceptorContext, InterceptorNext, Interceptor} from "@tsed/di";
@Interceptor()
export class MyInterceptor implements InterceptorMethods {
/**
* ctx: The context that holds the dynamic data related to the method execution and the proceed method
* to proceed with the original method execution
*
* opts: Static params that can be provided when the interceptor is attached to a specific method
*/
async intercept(context: InterceptorContext<any>, next: InterceptorNext) {
console.log(`the method ${context.propertyKey} will be executed with args ${context.args} and static data ${context.options}`);
// let the original method by calling next function
const result = await next();
console.log(`the method was executed, and returned ${result}`);
// must return the returned value back to the caller
return result;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Use the interceptor
Now that your interceptor logic is in place, you can use it in any other service. You need to use the @Intercept(InterceptorClass, opts)
annotation to register which interceptor should be used for the specific method you want to intercept. An example service in src/services/MyService.ts
:
import {Intercept, Injectable} from "@tsed/di";
import {MyInterceptor} from "../interceptors/MyInterceptor";
@Injectable()
export class MyService {
// MyInterceptor is going to be used to intercept this method whenever called
// 'simple data' is static data that will be passed as second arg to the interceptor.intercept method
@Intercept(MyInterceptor, "simple data")
mySimpleMethod() {
console.log("the simple method is executed");
}
}
// on class
@Injectable()
@Intercept(MyInterceptor, "simple data")
export class MyService2 {
mySimpleMethod1() {
console.log("the simple method is executed");
}
mySimpleMethod2() {
console.log("the simple method is executed");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
If the service method is executed like myServiceInstance.mySimpleMethod()
we will get the following output:
the method mySimpleMethod will be executed with args and static data simple data
the simple method is executed
the method was executed, and returned undefined
2
3
Last Updated: 2/5/2023, 1:16:22 PM
Other topics
- Session & cookies
- Passport.js
- Keycloak
- Prisma
- TypeORM
- MikroORM
- Mongoose
- GraphQL
- Socket.io
- Swagger
- AJV
- Multer
- Serve static files
- Templating
- Serverless HTTP
- Seq
- OIDC
- Stripe
- Agenda
- Terminus
- Serverless
- IORedis
- Controllers
- Providers
- Model
- JsonMapper
- Middlewares
- Pipes
- Interceptors
- Authentication
- Hooks
- Exceptions
- Throw HTTP Exceptions
- Cache
- Command
- Response Filter
- Injection scopes
- Custom providers
- Lazy-loading provider
- Custom endpoint decorator
- Testing
- Customize 404