Skip to content

interceptors

John Biundo edited this page Aug 25, 2019 · 2 revisions

Interceptors Chapter

With this chapter, if you want to follow along, check out the interceptors-start branch and go to the following along section.

If you just want a final version of the project as of the end of the chapter, check out the interceptors-end branch, and proceed to the Upon completion section.

Following along

Refer to the comments below, corresponding to chapter sections, to guide you through the code changes for nest cats as you proceed through the docs chapter.

Read through the Interceptors chapter until you get to the Aspect interception section, then return here.

Aspect interception section - creating a logging interceptor

When you get to the Aspect interception section of the docs, go ahead and create the logging.interceptor.ts file as described. As usual, we'll first create src/common/interceptors, and place the file in that folder. Your folder structure should now look like:

nest-cats
└───src
    └───cats
    │   └───dto
    │   └───interfaces
    └───common
        └───filters
        └───guards
        └───interceptors
        └───middleware
        └───pipes

Binding interceptors section

Now, go ahead and bind the interceptor to the controller scope as shown at the top of the Binding interceptors section. Don't forget to import UseInterceptors from @nestjs/common, and your custom LoggingInterceptor from src/common/interceptors.

HTTPie requests to test the logging interceptor

Run any of the requests to see the logging interceptor at work (check console output):

Create a cat

http POST :3000/cats name=Fred age:=3 breed='Alley Cat'

Query cats

http GET :3000/cats

Response Mapping section

When you get to the Response mapping section of the docs, go ahead and create the src/common/interceptors/transform.interceptor.ts file as described.

Then bind that to the CatsController (this step is not directly shown in the docs). Your src/cats/cats.controller.ts file should look like this:

...
import { TransformInterceptor } from '../common/interceptors/transform.interceptor';

@Controller('cats')
@UseInterceptors(LoggingInterceptor, TransformInterceptor)
export class CatsController {
...
HTTPie requests to test the response mapping interceptor

You can test with the standard create and query requests:

Create a cat

http POST :3000/cats name=Fred age:=3 breed='Alley Cat'

Query cats

http GET :3000/cats

Notice that with the create request, you now get an empty JSON object ({}) body response (previously, we returned a 201 HTTP response, and an empty body). This is because our interceptor is wrapping every response, after it is created, in a literal object. We might want to modify TransformInterceptor to avoid this side-effect (this code change is not shown in the docs):

...
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>> {
  intercept(
    context: ExecutionContext,
    next: CallHandler,
  ): Observable<Response<T>> {
    return next.handle().pipe(map(data => (data ? { data } : undefined)));
  }
}
...

Appendix

In the future, we plan to cover exception mapping, stream overriding, and more RxJS operators here.

Upon completion

We're done. We've tested our interceptors as we went along.

What's next

Next up is the Custom decorators chapter.