done with backend

This commit is contained in:
Kfir Dayan 2024-01-21 12:36:02 +02:00
parent b5d60f7e69
commit c241d90c45
3 changed files with 35 additions and 18 deletions

View file

@ -0,0 +1,5 @@
export interface ApiResponse {
data?: string;
error?: string;
status: number;
}

View file

@ -1,26 +1,35 @@
import { Controller, Post, Body, Get, Param, Redirect, HttpException, HttpStatus } from '@nestjs/common'; import { Controller, Post, Body, Get, Param, HttpException, HttpStatus, Res } from '@nestjs/common';
import { UrlShortenerService } from './url-shortener.service'; import { UrlShortenerService } from './url-shortener.service';
import { ApiResponse } from './response.interface';
import { Response } from 'express';
@Controller('url-shortener') @Controller('url-shortener')
export class UrlShortenerController { export class UrlShortenerController {
constructor(private readonly urlShortenerService: UrlShortenerService) {} constructor(private readonly urlShortenerService: UrlShortenerService) {}
@Post('shorten') @Post('shorten')
async shortenUrl(@Body('url') url: string): Promise<{ shortUrl: string }> { async shortenUrl(@Body('url') url: string): Promise<ApiResponse> {
if (!url) { if (!url) {
throw new HttpException('URL is required', HttpStatus.BAD_REQUEST); throw new HttpException('URL is required', HttpStatus.BAD_REQUEST);
} }
const shortUrl = await this.urlShortenerService.generateShortUrl(url); try {
return { shortUrl }; const shortUrl = await this.urlShortenerService.generateShortUrl(url);
return { data: shortUrl, status: HttpStatus.CREATED };
} catch (error) {
return { error: error.message, status: HttpStatus.BAD_REQUEST };
}
} }
@Get(':shortUrl') @Get(':shortUrl')
@Redirect() async resolveShortUrl(@Param('shortUrl') shortUrl: string, @Res() res: Response) {
async resolveShortUrl(@Param('shortUrl') shortUrl: string) { try {
const originalUrl = this.urlShortenerService.getOriginalUrl(shortUrl); const originalUrl = this.urlShortenerService.getOriginalUrl(shortUrl);
if (!originalUrl) { if (!originalUrl) {
throw new HttpException('URL not found!', HttpStatus.NOT_FOUND); return res.redirect('http://localhost:3000/404');
}
return res.redirect(originalUrl);
} catch (error) {
throw new HttpException('An error occurred', HttpStatus.INTERNAL_SERVER_ERROR);
} }
return { url: originalUrl };
} }
} }

View file

@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import * as shortid from 'shortid'; import * as shortid from 'shortid';
import { DnsService } from '../dns/dns.service'; import { DnsService } from '../dns/dns.service';
import { HttpException, HttpStatus } from '@nestjs/common';
@Injectable() @Injectable()
@ -11,19 +12,21 @@ export class UrlShortenerService {
constructor(private readonly dnsService: DnsService) {} constructor(private readonly dnsService: DnsService) {}
async generateShortUrl(originalUrl: string): Promise<string> { async generateShortUrl(originalUrl: string): Promise<string> {
if(!originalUrl) { if (!originalUrl) {
throw new Error('URL is required'); throw new HttpException('URL is required', HttpStatus.BAD_REQUEST);
} }
let isValid = await this.dnsService.isValidUrl(originalUrl); const isValid = await this.dnsService.isValidUrl(originalUrl);
if(!isValid) { if (!isValid) {
throw new Error('URL is invalid'); throw new HttpException('URL is invalid', HttpStatus.BAD_REQUEST);
} }
let shortUrl = "tiny." + shortid.generate() + ".com"; const shortUrl = "tiny." + shortid.generate() + ".com";
this.urlMap.set(shortUrl, originalUrl); this.urlMap.set(shortUrl, originalUrl);
return shortUrl return shortUrl;
} }
getOriginalUrl(shortUrl: string): string | undefined { getOriginalUrl(shortUrl: string): string | undefined {
return this.urlMap.get(shortUrl); let url: string | undefined = this.urlMap.get(shortUrl);
if (url) return url;
return undefined;
} }
} }