作者选择了(https://www.brightfunds.org/funds/tech-education)作为 写给捐款计划的一部分的捐款。
介绍
URL,简称为 Uniform Resource Locator,是网页上一个独特资源的地址,因为一个URL是独一无二的,所以没有两个资源可以有相同的URL。
URL 的长度和复杂性会有所不同. 一个 URL 可能会短到 example.com
或长到 http://llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk
. 复杂的 URL 可能会很糟糕,导致搜索引擎优化(SEO)问题,并对营销计划产生负面影响。 URL 缩短器将长的 URL 转化为更短的 URL,并在使用短的 URL 时将用户重定向到原始的 URL。
在本教程中,您将使用 NestJS创建一个 URL 缩短器。 首先,您将在 服务中实现 URL 缩短和重定向逻辑。
前提条件
要遵循本教程,您将需要:
- 适用于 Node.js版本 16 或更高版本的本地开发环境. 遵循 如何安装 Node.js 和创建本地开发环境教程,适合您的系统。 * 在您的系统上安装的 NestJS CLI,您将在步骤 1 中设置,并熟悉 NestJS. 审查 开始使用 NestJS。 * 熟悉 TypeScript。
步骤一:准备你的发展环境
在此步骤中,您将设置所需的一切,以便开始实施您的 URL 缩短逻辑. 您将在全球范围内安装 NestJS,生成新的 NestJS 应用程序锅炉,安装依赖,并创建您的项目的模块,服务和控制器。
首先,如果您之前没有安装它,您将在全球范围内安装 Nest CLI. 您将使用此 CLI 生成您的项目目录和所需的文件。
1npm install -g @nestjs/cli
-g
旗帜将在您的系统上全球安装Nest CLI。
您将看到以下结果:
1[secondary_label Output]
2...
3added 249 packages, and audited 250 packages in 3m
439 packages are looking for funding
5run npm fund for details
6found 0 vulnerabilities
然后,您将使用新
命令创建项目并生成必要的锅炉板启动文件:
1nest new URL-shortener
您将看到以下结果:
1[secondary_label Output]
2...
3⚡ We will scaffold your app in a few seconds..
4
5CREATE url-shortener/.eslintrc.js (631 bytes)
6CREATE url-shortener/.prettierrc (51 bytes)
7CREATE url-shortener/nest-cli.json (118 bytes)
8CREATE url-shortener/package.json (2002 bytes)
9CREATE url-shortener/README.md (3339 bytes)
10CREATE url-shortener/tsconfig.build.json (97 bytes)
11CREATE url-shortener/tsconfig.json (546 bytes)
12CREATE url-shortener/src/app.controller.spec.ts (617 bytes)
13CREATE url-shortener/src/app.controller.ts (274 bytes)
14CREATE url-shortener/src/app.module.ts (249 bytes)
15CREATE url-shortener/src/app.service.ts (142 bytes)
16CREATE url-shortener/src/main.ts (208 bytes)
17CREATE url-shortener/test/app.e2e-spec.ts (630 bytes)
18CREATE url-shortener/test/jest-e2e.json (183 bytes)
19
20? Which package manager would you ❤️ to use? (Use arrow keys)
21> npm
22 yarn
23 pnpm
选择npm
。
你会看到以下的输出:
1[secondary_label Output]
2√ Installation in progress... ☕
3
4🚀 Successfully created project url-shortener
5👉 Get started with the following commands:
6
7$ cd url-shortener
8$ npm run start
9
10 Thanks for installing Nest 🙏
11 Please consider donating to our open collective
12 to help us maintain this package.
13
14 🍷 Donate: https://opencollective.com/nest
转到您创建的项目目录:
1cd url-shortener
您将在此目录中运行所有后续命令。
注意:NestJS CLI在创建新项目时会创建app.controller.ts
,app.controller.spec.ts
和app.service.ts
文件。
接下来,您将安装所需的依赖。
本教程需要使用 NodeJS 的默认包管理器 npm安装一些依赖性,所需依赖性包括 TypeORM, SQLite, Class-validator, Class-transformer和 Nano-ID。
TypeORM是一个对象关系地图器,可促进TypeScript应用程序和关系数据库之间的交互。由于NestJS专用的@nestjs/typeorm’包,这个ORM与NestJS无缝工作。
运行以下命令来安装 TypeORM 及其专用 NestJS 包:
1npm install @nestjs/typeorm typeorm
SQLite是一个实现小,快速,自含的SQL数据库引擎的库,您将使用这种依赖作为您的数据库来存储和检索缩短的URL。
运行以下命令来安装 SQLite:
1npm install sqlite3
该 class-validator
包包含用于NestJS数据验证的装饰器,您将使用此依赖性与您的数据传输对象来验证向您的应用程序发送的数据。
运行以下命令来安装class-validator
:
1npm install class-validator
class-transformer
包允许您将普通对象转换为一个类的实例,反之亦然.您将使用这个依赖性与‘class-validator’一起使用,因为它不能单独工作。
运行以下命令来安装class-transformer
:
1npm install class-transformer
Nano-ID是一个安全的, URL 友好的单一字符串 ID 生成器,您将使用这种依赖性来生成每个 URL 资源的单一 ID。
运行以下命令来安装 Nano-ID:
1npm install nanoid@^3.0.0
<$>[注] 注: Nano-ID 的版本高于 3.0.0
禁用了对 CommonJS 模块的支持. 此问题可能会导致应用程序中的错误,因为 TypeScript 编译器产生的 JavaScript 代码仍然使用 CommonJS 模块系统。
安装所需的依赖性后,您将使用 Nest CLI 生成项目的模块、服务和控制器,该模块将组织您的项目,服务将处理 URL 缩写器的所有逻辑,控制器将处理路线。
运行以下命令来生成您的模块:
1nest generate module url
您将看到以下结果:
1[secondary_label Output]
2CREATE src/url/url.module.ts (80 bytes)
3UPDATE src/app.module.ts (304 bytes)
接下来,运行以下命令来生成您的服务:
1nest generate service url --no-spec
「--no-spec」的旗帜告诉Nest CLI在没有测试文件的情况下生成文件,您不需要本教程中的测试文件。
您将看到以下结果:
1[secondary_label Output]
2CREATE src/url/url.service.ts (87 bytes)
3UPDATE src/url/url.module.ts (151 bytes)
然后运行以下命令来生成您的控制器:
1nest generate controller url --no-spec
您将看到以下结果:
1[secondary_label Output]
2CREATE src/url/url.controller.ts (95 bytes)
3UPDATE src/url/url.module.ts (233 bytes)
在此步骤中,您生成了您的应用程序和开发所需的大部分文件,然后将您的应用程序连接到数据库。
步骤 2 – 将应用程序连接到数据库
在此步骤中,您将创建一个实体来模拟数据库中的 URL 资源. entity 是一个包含存储数据所需属性的文件。
使用nano
或您偏好的文本编辑器,创建并打开名为url.entity.ts
的src/url
文件夹中的文件:
1nano src/url/url.entity.ts
此文件将包含模型您的数据的实体。
接下来,在您的 src/url/url.entity.ts
文件中,添加以下 Typescript 代码:
1[label src/url/url.entity.ts]
2import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
3
4@Entity()
5export class Url {
6 @PrimaryGeneratedColumn()
7 id: number;
8
9 @Column()
10 urlCode: string;
11
12 @Column()
13 longUrl: string;
14
15 @Column()
16 shortUrl: string;
17}
首先,您从typeorm
中导入实体
、列
和PrimaryGeneratedColumn
的装饰。
该代码创建并导出一个类URL
,注明与实体
装饰器标记一个类为实体。
每个属性都被指定并注明了相应的装饰器:ID的PrimaryGeneratedColumn
和其他属性的Column
。PrimaryGeneratedColumn
是一个装饰器,自动生成它注释的属性的值。
应该存储在数据库中的属性包括:
id
是数据库表的主要密钥。 *urlCode
是由nanoid
包生成的独特 ID,将用于识别每个 URL。
保存并关闭文件。
接下来,您将创建应用程序和数据库之间的连接。
首先,在nano
或您喜爱的文本编辑器中打开src/app.module.ts
:
1nano src/app.module.ts
然后,将突出的行添加到文件中:
1[label src/app.module.ts]
2import { Module } from '@nestjs/common';
3import { TypeOrmModule } from '@nestjs/typeorm';
4import { Url } from './url/url.entity';
5import { UrlModule } from './url/url.module';
6
7@Module({
8 imports: [
9 TypeOrmModule.forRoot({
10 type: 'sqlite',
11 database: 'URL.sqlite',
12 entities: [Url],
13 synchronize: true,
14 }),
15 UrlModule,
16 ],
17 controllers: [],
18 providers: [],
19})
20export class AppModule {}
首先,从@nestjs/typeorm
导入TypeOrmModule
和Url
从./url/url.entity
。你仍然可能有与AppController
和AppService
相关的行。
在导入数组中,在TypeOrmModule
上调用forRoot
方法来通过应用程序中的所有模块共享连接。
配置对象包含创建连接的属性. 这些属性包括以下内容:
*类型
属性表示您正在使用 TypeOrm 进行交互的数据库类型。在这种情况下,它被设置为sqlite
。 *数据库
属性表示数据库的偏好名称。在这种情况下,它被设置为URL.sqlite
。 *实体
属性是项目中的所有实体的组合。
注意: ** 将同步
设置为真
仅在开发环境中是理想的。
保存并关闭文件。
接下来,您将创建一个存储库,作为应用程序和数据库之间的访问层,您需要将实体连接到其母模块,并且这种连接允许Nest和TypeOrm自动创建一个存储库。
打开src/url/url.module.ts
:
1nano src/url/url.module.ts
在现有文件中,添加突出的行:
1[label src/url/url.module.ts]
2import { Module } from '@nestjs/common';
3import { UrlService } from './url.service';
4import { UrlController } from './url.controller';
5import { TypeOrmModule } from '@nestjs/typeorm';
6import { Url } from './url.entity';
7
8@Module({
9 imports: [TypeOrmModule.forFeature([Url])],
10 providers: [UrlService],
11 controllers: [UrlController],
12})
13export class UrlModule {}
您在模块
装饰器中创建一个导入
数组,在那里您从@nestjs/typeorm
导入TypeOrmModule
和Url
从./url.entity
。
保存并关闭文件。
Nest 和 TypeOrm 将创建一个幕后存储库,作为服务和数据库之间的访问层。
在此步骤中,您已将应用程序连接到数据库,现在您已准备好实现 URL 缩短逻辑。
步骤三:实施服务逻辑
在此步骤中,您将用两种方法实现您的服务逻辑。第一个方法,‘shortenUrl’,将包含所有URL缩写逻辑。第二种方法,‘redirect’,将包含所有逻辑来将用户重定向到原始URL。
提供服务访问存储库
在实施这些方法之前,您将为您的服务提供存储库访问权限,以便您的应用程序能够在数据库中阅读和写入数据。
首先,打开src/url/url.service.ts
:
1nano src/url/url.service.ts
将以下突出的行添加到现有文件中:
1[label src/url/url.service.ts]
2import { Injectable } from '@nestjs/common';
3import { Repository } from 'typeorm';
4import { InjectRepository } from '@nestjs/typeorm';
5import { Url } from './url.entity';
6
7@Injectable()
8export class UrlService {
9 constructor(
10 @InjectRepository(Url)
11 private repo: Repository<Url>,
12 ) {}
13}
您从typeorm
导入Repository
,从@nestjs/typeorm
导入InjectRepository
,从./url.entity
导入Url
。
在你的UrlService
类中,你创建一个constructor
。在constructor
内部,你宣布一个私有变量,repo,作为参数。然后,你将一个类型的Repository
分配给repo
用一个通用类型的Url
。
保存并关闭文件。
您的服务现在可以通过repo
变量访问您的存储库,所有数据库查询和TypeOrm方法将被调用。
接下来,您将创建一个非同步的方法,即shortenUrl
。该方法将采取一个URL作为论点,并返回一个缩短的URL。
创建数据传输对象
在创建非同步方法之前,您将创建 shortenUrl
async 方法所需的数据传输对象. data-transfer object 是定义如何在应用程序之间发送数据的对象。
首先,在您的URL文件夹中创建一个dtos
(数据传输对象)文件夹:
1mkdir src/url/dtos
然后,在该文件夹中创建一个名为url.dto.ts
的文件:
1nano src/url/dtos/url.dto.ts
将以下代码添加到新文件中:
1[label src/url/dto/url.dto.ts]
2import { IsString, IsNotEmpty } from 'class-validator';
3
4export class ShortenURLDto {
5 @IsString()
6 @IsNotEmpty()
7 longUrl: string;
8}
您从类验证器
导入IsString
和IsNotEmpty
装饰器,然后创建并导出ShortenURLDto
类。
您还会用IsString
和IsNotEmpty
装饰符标注longUrl
属性,并且使用这些装饰符标注longUrl
属性将确保longUrl
始终是一个字符串,而不是空。
保存并关闭文件。
然后,打开您的src/main.ts
文件:
1nano src/main.ts
将突出的代码添加到现有文件中:
1[label src/main.ts]
2import { NestFactory } from '@nestjs/core';
3import { AppModule } from './app.module';
4import { ValidationPipe } from '@nestjs/common';
5
6async function bootstrap() {
7 const app = await NestFactory.create(AppModule);
8 app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
9 await app.listen(3000);
10}
11bootstrap();
您导入验证管
,它使用类验证器
包来执行验证规则对所有进入您的应用程序的数据。
然后,您在您的应用程序实例(应用
)上调用useGlobalPipes
方法,并将一个ValidationPipe
实例传递给一个选项对象,其中whitelist
属性设置为true
。useGlobalPipes
方法将ValidationPipe
绑定到应用程序级别,确保所有路径都免受错误的数据。
保存并关闭文件。
接下来,您将将数据传输对象导入到url.service.ts
文件中,并将其应用到shortenUrl
方法。
创建shortenUrl
方法
shortenUrl
方法将处理大部分的URL缩短逻辑,它将采用类型的ShortenURLDto
的参数url
。
首先,打开您的src/url/url.service.ts
文件:
1nano src/url/url.service.ts
将突出的行添加到文件中:
1[label src/url/url.service.ts]
2import {
3 BadRequestException,
4 Injectable,
5 NotFoundException,
6 UnprocessableEntityException,
7} from '@nestjs/common';
8import { Repository } from 'typeorm';
9import { InjectRepository } from '@nestjs/typeorm';
10import { Url } from './url.entity';
11import { ShortenURLDto } from './dtos/url.dto';
12import { nanoid } from 'nanoid';
13import { isURL } from 'class-validator';
14...
首先,您将从@nestjs/common
导入NotFoundExeception
,BadRequestException
和UnprocessableEntityException
,因为您将使用它们来处理错误。然后,您将从nanoid
导入{nanoid}
,从class-validator
导入isURL
。
然后,在constructor
下方添加以下内容到UrlService
类:
1[label src/url/url.service.ts]
2...
3async shortenUrl(url: ShortenURLDto) {}
然后,将以下代码添加到您的shortenUrl
方法:
1[label src/url/url.service.ts]
2...
3 const { longUrl } = url;
4
5 //checks if longurl is a valid URL
6 if (!isURL(longUrl)) {
7 throw new BadRequestException('String Must be a Valid URL');
8 }
9
10 const urlCode = nanoid(10);
11 const baseURL = 'http://localhost:3000';
12
13 try {
14 //check if the URL has already been shortened
15 let url = await this.repo.findOneBy({ longUrl });
16 //return it if it exists
17 if (url) return url.shortUrl;
18
19 //if it doesn't exist, shorten it
20 const shortUrl = `${baseURL}/${urlCode}`;
21
22 //add the new record to the database
23 url = this.repo.create({
24 urlCode,
25 longUrl,
26 shortUrl,
27 });
28
29 this.repo.save(url);
30 return url.shortUrl;
31 } catch (error) {
32 console.log(error);
33 throw new UnprocessableEntityException('Server Error');
34 }
在上面的代码块中,longUrl
被从url
对象中解构出来,然后,使用isURL
方法,一个检查会验证longUrl
是否是一个有效的URL。
使用nanoid
生成一个urlCode
。默认情况下,nanoid
生成一个独特的二十一个字符串。 将所需的长度作为一个论点来排除默认行为。
然后,定义了基础 URL. 基础 URL 是您的网站地址的一致根。 在开发中,它是您的本地主机服务器;在生产中,它是您的域名。
一个试捕
块将容纳所有代码与数据库进行交互,以便处理错误。
将 URL 缩短两次可能会导致数据重复,因此在数据库中运行搜索查询,以查看 URL 是否存在. 如果 URL 存在,则将返回其 shortUrl;否则,代码将继续缩短它.如果数据库中没有 URL 记录,则通过将
baseURL和
urlCode' 连接来创建一个短 URL。
然后,使用urlCode
,longUrl
和shortUrl
创建一个url
实例。将url
实例保存到数据库中,通过在repo
上调用save
方法并将该实例作为一个参数。
最后,如果出现错误,错误将登录到捕获区块中的控制台,并将投放一个UnprocessableEntityException
消息。
现在你的url.service.ts
文件将是这样的:
1[label src/url/url.service.ts]
2import {
3 BadRequestException,
4 Injectable,
5 NotFoundException,
6 UnprocessableEntityException,
7} from '@nestjs/common';
8import { Repository } from 'typeorm';
9import { InjectRepository } from '@nestjs/typeorm';
10import { Url } from './url.entity';
11import { ShortenURLDto } from './dtos/url.dto';
12import { nanoid } from 'nanoid';
13import { isURL } from 'class-validator';
14
15@Injectable()
16export class UrlService {
17 constructor(
18 @InjectRepository(Url)
19 private repo: Repository<Url>,
20 ) {}
21
22 async shortenUrl(url: ShortenURLDto) {
23 const { longUrl } = url;
24
25 //checks if longurl is a valid URL
26 if (!isURL(longUrl)) {
27 throw new BadRequestException('String Must be a Valid URL');
28 }
29
30 const urlCode = nanoid(10);
31 const baseURL = 'http://localhost:3000';
32
33 try {
34 //check if the URL has already been shortened
35 let url = await this.repo.findOneBy({ longUrl });
36 //return it if it exists
37 if (url) return url.shortUrl;
38
39 //if it doesn't exist, shorten it
40 const shortUrl = `${baseURL}/${urlCode}`;
41
42 //add the new record to the database
43 url = this.repo.create({
44 urlCode,
45 longUrl,
46 shortUrl,
47 });
48
49 this.repo.save(url);
50 return url.shortUrl;
51 } catch (error) {
52 console.log(error);
53 throw new UnprocessableEntityException('Server Error');
54 }
55 }
56}
保存檔案
在这里,您设置了URL缩短逻辑的第一部分,接下来,您将在您的服务中实施重定向
方法。
创建重定向
方法
重定向
方法将包含将用户重定向到长URL的逻辑。
在src/url/url/service.ts
文件中,将以下代码添加到您的UrlService
类底部,以实现重定向
方法:
1[label src/url/url.service.ts]
2...
3 async redirect(urlCode: string) {
4 try {
5 const url = await this.repo.findOneBy({ urlCode });
6 if (url) return url;
7 } catch (error) {
8 console.log(error);
9 throw new NotFoundException('Resource Not Found');
10 }
11 }
该重定向
方法将urlCode
作为参数,并尝试在数据库中找到与urlCode
匹配的资源。
您的完成的url.service.ts
文件现在将看起来像这样:
1[label src/url/url.service.ts]
2import {
3 BadRequestException,
4 Injectable,
5 NotFoundException,
6 UnprocessableEntityException,
7} from '@nestjs/common';
8import { Repository } from 'typeorm';
9import { InjectRepository } from '@nestjs/typeorm';
10import { Url } from './url.entity';
11import { ShortenURLDto } from './dtos/url.dto';
12import { nanoid } from 'nanoid';
13import { isURL } from 'class-validator';
14
15@Injectable()
16export class UrlService {
17 constructor(
18 @InjectRepository(Url)
19 private repo: Repository<Url>,
20 ) {}
21
22 async shortenUrl(url: ShortenURLDto) {
23 const { longUrl } = url;
24
25 //checks if longurl is a valid URL
26 if (!isURL(longUrl)) {
27 throw new BadRequestException('String Must be a Valid URL');
28 }
29
30 const urlCode = nanoid(10);
31 const baseURL = 'http://localhost:3000';
32
33 try {
34 //check if the URL has already been shortened
35 let url = await this.repo.findOneBy({ longUrl });
36 //return it if it exists
37 if (url) return url.shortUrl;
38
39 //if it doesn't exist, shorten it
40 const shortUrl = `${baseURL}/${urlCode}`;
41
42 //add the new record to the database
43 url = this.repo.create({
44 urlCode,
45 longUrl,
46 shortUrl,
47 });
48
49 this.repo.save(url);
50 return url.shortUrl;
51 } catch (error) {
52 console.log(error);
53 throw new UnprocessableEntityException('Server Error');
54 }
55 }
56
57 async redirect(urlCode: string) {
58 try {
59 const url = await this.repo.findOneBy({ urlCode });
60 if (url) return url;
61 } catch (error) {
62 console.log(error);
63 throw new NotFoundException('Resource Not Found');
64 }
65 }
66}
保存并关闭文件。
您的 URL 缩短逻辑现在完成了两种方法:一种是缩短 URL,另一种是将缩短 URL 重定向到原始 URL。
在下一步中,您将在控制器类中实现这两种方法的路由处理器。
步骤 4 – 实施控制器逻辑
在此步骤中,您将创建两个路由处理器:一个POST
路由处理器来处理缩短请求和一个GET
路由处理器来处理重定向请求。
在部署控制器类中的路由之前,您必须向控制器提供该服务。
首先,打开您的src/url/url.controller.ts
文件:
1nano src/url/url.controller.ts
将突出的行添加到文件中:
1[label src/url/url.controller.ts]
2import { Controller } from '@nestjs/common';
3import { UrlService } from './url.service';
4
5@Controller('url')
6export class UrlController {
7 constructor(private service: UrlService) {}
8}
首先,您将UrlService
从./url.service
导入,然后,在控制器类中,您声明一个构建器,并将一个私有变量服务
作为参数。
控制器
设计器目前有一个字符串,url
作为一个论点,这意味着控制器只会处理到localhost/3000/url/route
的请求。这种行为会引入您的 URL 缩短逻辑中的错误,因为缩短的 URL 包含一个基础 url(localhost:3000
)和一个 URL 代码(wyt4_uyP-Il
),这些请求将组成一个新的 URL(localhost:3000/wyt4_uyP-Il
).因此,这个控制器无法处理请求,而缩短的链接将返回一个404 Not Found
错误。
删除url
参数后,您的UrlController
将是这样的:
1[label src/url/url.controller.ts]
2@Controller()
3export class UrlController {
4 constructor(private service: UrlService) {}
5}
在src/url/url.controller.ts
文件中,将突出的项目添加到进口
声明中:
1[label src/url/url.controller.ts]
2import { Body, Controller, Get, Param, Post, Res } from '@nestjs/common';
3import { UrlService } from './url.service';
4import { ShortenURLDto } from './dtos/url.dto';
您从@nestjs/common
和ShortenURLDto
从./dtos/url.dto
中导入Body
,Get
,Param
,Post
和Res
。
然后将下列行添加到Constructor
下面的UrlController
,以定义POST
路径处理器:
1[label src/url/url.controller.ts]
2...
3 @Post('shorten')
4 shortenUrl(
5 @Body()
6 url: ShortenURLDto,
7 ) {
8 return this.service.shortenUrl(url);
9 }
您创建了一个方法 shortenUrl
,它使用一个词汇符号 url
和一个类型的 ShortenURLDto
. 您使用 Body
装饰器注释 url
以从请求对象中提取身体对象,并填充 url
变量与其值。
然后,您使用邮件
装饰器对整个方法进行注释,并将缩短
作为参数。 此处理器将处理所有发送到Localhost:<port>/shorten
的邮件请求。
接下来,在POST
路线下方添加以下行,以定义重定向的GET
路线处理器:
1[label src/url/url.controller.ts]
2...
3 @Get(':code')
4 async redirect(
5 @Res() res,
6 @Param('code')
7 code: string,
8 ) {
9 const url = await this.service.redirect(code);
10
11 return res.redirect(url.longUrl);
12 }
您创建一个有两个参数的重定向
方法:res
,用Res
装饰器注释,和代码
,用Param
装饰器注释。Res
装饰器(https://docs.nestjs.com/controllers# routing)将它注释的类转化为 Express 响应对象,允许您使用图书馆特定的命令,如Express
装置。
您使用Get
装饰器注明重定向
方法,并传递一个野卡参数:代码
然后将代码
作为参数传递给Param
装饰器。
然后在服务
上调用重定向
方法,等待
结果,并将其存储在变量中,即url
。
最后,您返回res.redirect()
并将url.longUrl
作为参数,该方法将处理GET
请求到localhost:<port>/code
,或您的缩短的URL。
您的「src/url/url.controller.ts」文件现在将看起来像这样:
1[label src/url/url.controller.ts]
2import { Body, Controller, Get, Param, Post, Res } from '@nestjs/common';
3import { UrlService } from './url.service';
4import { ShortenURLDto } from './dtos/url.dto';
5
6@Controller()
7export class UrlController {
8 constructor(private service: UrlService) {}
9
10 @Post('shorten')
11 shortenUrl(
12 @Body()
13 url: ShortenURLDto,
14 ) {
15 return this.service.shortenUrl(url);
16 }
17
18 @Get(':code')
19 async redirect(
20 @Res() res,
21 @Param('code')
22 code: string,
23 ) {
24 const url = await this.service.redirect(code);
25
26 return res.redirect(url.longUrl);
27 }
28}
保存并关闭文件。
现在你已经定义了你的POST
和GET
路由处理器,你的URL缩短器是完全功能的。
步骤 5 – 测试 URL 缩短器
在此步骤中,您将测试您在上一个步骤中定义的 URL 缩短器。
首先,启动您的应用程序,运行:
1npm run start
您将看到以下结果:
1[secondary_label Output]
2[Nest] 12640 - 06/08/2022, 16:20:04 LOG [NestFactory] Starting Nest application...
3[Nest] 12640 - 06/08/2022, 16:20:07 LOG [InstanceLoader] AppModule dependencies initialized +2942ms
4[Nest] 12640 - 06/08/2022, 16:20:07 LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms
5[Nest] 12640 - 06/08/2022, 16:20:08 LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +257ms
6[Nest] 12640 - 06/08/2022, 16:20:08 LOG [InstanceLoader] TypeOrmModule dependencies initialized +2ms
7[Nest] 12640 - 06/08/2022, 16:20:08 LOG [InstanceLoader] UrlModule dependencies initialized +4ms
8[Nest] 12640 - 06/08/2022, 16:20:08 LOG [RoutesResolver] UrlController {/}: +68ms
9[Nest] 12640 - 06/08/2022, 16:20:08 LOG [RouterExplorer] Mapped {/shorten, POST} route +7ms
10[Nest] 12640 - 06/08/2022, 16:20:08 LOG [RouterExplorer] Mapped {/:code, GET} route +2ms
11[Nest] 12640 - 06/08/2022, 16:20:08 LOG [NestApplication] Nest application successfully started +7ms
打开一个新的终端,使用‘curl’或您喜爱的API测试工具,向‘http://localhost:3000/shorten’发出‘POST’请求,其中包含下面的数据或您所选择的任何数据。
运行此命令以创建样本POST
请求:
1[environment second]
2curl -d "{\"longUrl\":\"http://llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk\"}" -H "Content-Type: application/json" http://localhost:3000/shorten
-d
旗记录了HTTP POST
请求数据,而-H
旗则为HTTP
请求设置了标题。
您将收到一个短的 URL 作为回复,例如下面的示例:
1[environment second]
2http://localhost:3000/MWBNHDiloW
最后,复制短的URL并将链接粘贴到您的浏览器中,然后按ENTER
。
结论
在本文中,您使用 NestJS 创建了一个 URL 缩写器. 如果您添加了 前端接口,您可以将其部署用于公共用途。
NestJS 提供类型安全和架构,使您的应用程序更安全,可维护和可扩展。 有关更多信息,请访问 NestJS 官方文档。