adding routes and service logic to url-shortener
This commit is contained in:
parent
ac79ea9ad3
commit
b48f806da4
7 changed files with 68 additions and 22 deletions
24
package-lock.json
generated
24
package-lock.json
generated
|
@ -13,7 +13,8 @@
|
||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1"
|
"rxjs": "^7.8.1",
|
||||||
|
"shortid": "^2.2.16"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^10.0.0",
|
"@nestjs/cli": "^10.0.0",
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/jest": "^29.5.2",
|
"@types/jest": "^29.5.2",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.1",
|
||||||
|
"@types/shortid": "^0.0.32",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||||
"@typescript-eslint/parser": "^5.59.11",
|
"@typescript-eslint/parser": "^5.59.11",
|
||||||
|
@ -2122,6 +2124,12 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/shortid": {
|
||||||
|
"version": "0.0.32",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/shortid/-/shortid-0.0.32.tgz",
|
||||||
|
"integrity": "sha512-LwWF89yy6Ol8abraYbVedIKzMlgJCTx8zm40yx9t0ZPOJaVR0OmSO4zRRAKfyOJtCwZrEBmhueZX8OiNbQydYw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||||
|
@ -6266,6 +6274,11 @@
|
||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "2.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
|
||||||
|
"integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA=="
|
||||||
|
},
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
|
@ -7425,6 +7438,15 @@
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/shortid": {
|
||||||
|
"version": "2.2.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz",
|
||||||
|
"integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==",
|
||||||
|
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/side-channel": {
|
"node_modules/side-channel": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1"
|
"rxjs": "^7.8.1",
|
||||||
|
"shortid": "^2.2.16"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^10.0.0",
|
"@nestjs/cli": "^10.0.0",
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/jest": "^29.5.2",
|
"@types/jest": "^29.5.2",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.1",
|
||||||
|
"@types/shortid": "^0.0.32",
|
||||||
"@types/supertest": "^2.0.12",
|
"@types/supertest": "^2.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||||
"@typescript-eslint/parser": "^5.59.11",
|
"@typescript-eslint/parser": "^5.59.11",
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import { Controller, Get } from '@nestjs/common';
|
import { Controller, Get } from '@nestjs/common';
|
||||||
import { AppService } from './app.service';
|
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(private readonly appService: AppService) {}
|
constructor() {}
|
||||||
|
|
||||||
@Get()
|
|
||||||
getHello(): string {
|
|
||||||
return this.appService.getHello();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
|
||||||
import { UrlShortenerModule } from './url-shortener/url-shortener.module';
|
import { UrlShortenerModule } from './url-shortener/url-shortener.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UrlShortenerModule],
|
imports: [UrlShortenerModule],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AppService {
|
|
||||||
getHello(): string {
|
|
||||||
return 'Hello World!';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,27 @@
|
||||||
import { Controller } from '@nestjs/common';
|
import { Controller, Post, Body, Get, Param, Redirect, HttpException, HttpStatus } from '@nestjs/common';
|
||||||
|
import { UrlShortenerService } from './url-shortener.service';
|
||||||
|
|
||||||
@Controller('url-shortener')
|
@Controller('url-shortener')
|
||||||
export class UrlShortenerController {
|
export class UrlShortenerController {
|
||||||
|
constructor(private readonly urlShortenerService: UrlShortenerService) {}
|
||||||
|
|
||||||
|
@Post('shorten')
|
||||||
|
shortenUrl(@Body('url') url: string): { shortUrl: string } {
|
||||||
|
// example route http://localhost:3000/url-shortener/shorten POST body { url: 'https://www.google.com' }
|
||||||
|
if (!url) {
|
||||||
|
throw new HttpException('URL is required', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
const shortUrl = this.urlShortenerService.generateShortUrl(url);
|
||||||
|
return { shortUrl };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':shortUrl')
|
||||||
|
@Redirect()
|
||||||
|
async resolveShortUrl(@Param('shortUrl') shortUrl: string) {
|
||||||
|
const originalUrl = this.urlShortenerService.getOriginalUrl(shortUrl);
|
||||||
|
if (!originalUrl) {
|
||||||
|
throw new HttpException('URL not found!', HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
return { url: originalUrl };
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,20 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import * as shortid from 'shortid';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UrlShortenerService {}
|
export class UrlShortenerService {
|
||||||
|
private urlMap = new Map<string, string>();
|
||||||
|
|
||||||
|
generateShortUrl(originalUrl: string): string {
|
||||||
|
if(!originalUrl) {
|
||||||
|
throw new Error('URL is required');
|
||||||
|
}
|
||||||
|
let shortUrl = shortid.generate();
|
||||||
|
this.urlMap.set(shortUrl, originalUrl);
|
||||||
|
return shortUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
getOriginalUrl(shortUrl: string): string | undefined {
|
||||||
|
return this.urlMap.get(shortUrl);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue