typescript
34 lines · 7 steps
Handling HTTP redirects in NestJS
A NestJS controller shows three ways to redirect: static, query-tuned, and database-resolved short links.
Explained by
highlit
1import { Controller, Get, Param, Query, Redirect, NotFoundException } from '@nestjs/common';
2import { LinksService } from './links.service';
3
4@Controller('links')
5export class LinksController {
6 constructor(private readonly linksService: LinksService) {}
7
8 @Get('docs')
9 @Redirect('https://docs.nestjs.com', 301)
10 toDocs() {}
11
12 @Get('version')
13 @Redirect('https://docs.nestjs.com')
14 version(@Query('v') version?: string) {
15 if (version === 'beta') {
16 return { url: 'https://docs.nestjs.com/next', statusCode: 302 };
17 }
18 return { url: 'https://docs.nestjs.com', statusCode: 301 };
19 }
20
21 @Get(':slug')
22 @Redirect()
23 async resolve(@Param('slug') slug: string) {
24 const link = await this.linksService.findBySlug(slug);
25
26 if (!link || link.expiresAt < new Date()) {
27 throw new NotFoundException(`No active link for '${slug}'`);
28 }
29
30 await this.linksService.recordVisit(link.id);
31
32 return { url: link.target, statusCode: link.permanent ? 301 : 302 };
33 }
34}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1The @Redirect decorator accepts a static target or lets the handler override url and statusCode by returning them.
- 2Returning statusCode 301 vs 302 controls whether a redirect is cached as permanent or treated as temporary.
- 3Throwing NotFoundException from a handler cleanly maps a missing resource to a 404 without manual response wiring.
Related explainers
typescript
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository, DeepPartial } from 'typeorm'; import { User } from './entities/user.entity';
Building a CRUD service in NestJS
crud
dependency-injection
repository-pattern
Intermediate
7 steps
go
package handlers import ( "context"
Liveness vs readiness health checks in Gin
health-checks
dependency-injection
context-timeout
Intermediate
7 steps
typescript
type AsyncMethod = (...args: any[]) => Promise<any>; function LogExecutionTime(thresholdMs = 0) { return function <T extends AsyncMethod>(
A method decorator that times async calls
decorators
higher-order-functions
async
Advanced
9 steps
rust
use axum::{ body::Body, http::{header, HeaderValue, StatusCode, Uri}, response::{IntoResponse, Response},
Serving embedded static files in Axum
static-assets
embedding
http-headers
Intermediate
7 steps
php
<?php namespace App\Queue;
A stable priority job queue in PHP
priority-queue
data-structures
closures
Intermediate
8 steps
python
import secrets from datetime import datetime, timedelta, timezone from fastapi import APIRouter, Cookie, Depends, HTTPException, Response, status
Cookie session auth in FastAPI
session-authentication
cookies
dependency-injection
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/handling-http-redirects-in-nestjs-explained-typescript-63f7/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.