Building a TypeScript-based URL Shortener using Docker

Ajeet Singh Raina - Jul 7 '22 - - Dev Community

TypeScript’s incremental adoption is attributable to enhancements in developer code quality and comprehensibility. Overall, Typescript encourages developers to thoroughly document their code and inspires greater confidence through ease of use. TypeScript offers every modern JavaScript feature while introducing powerful concepts like interfaces, unions, and intersection types. It improves developer productivity by clearly displaying syntax errors during compilation, rather than letting things fail at runtime.

However, remember that every programming language comes with certain drawbacks, and TypeScript is no exception. Long compilation times and a steeper learning curve for new JavaScript users are most noteworthy. The good news is that TypeScript’s pros outweigh its cons for ideal use cases. We’ll tackle one of those now.

Building Your Application

In this tutorial, you’ll learn how to build a basic URL shortener from scratch using TypeScript and Nest.

First, you’ll create a basic application in Nest without using Docker. You’ll see how the application lets you build a simple URL shortening service in Nest and TypeScript, with a Redis backend. Next, you’ll learn how Docker Compose can help you jointly run a Nest.js, TypeScript, and Redis backend to power microservices. Let’s jump in.

Getting Started

The following key components are essential to completing this walkthrough:

  • Node.js
  • NPM
  • VS Code
  • Docker Desktop

Before starting, make sure you have Node installed on your system. Then, follow these steps to build a simple web application with TypeScript.

Creating a Nest Project
Nest is currently the fastest growing server-side development framework in the JavaScript ecosystem. It’s ideal for writing scalable, testable, and loosely-coupled applications. Nest provides a level of abstraction above common Node.js frameworks and exposes their APIs to the developer. Under the hood, Nest makes use of robust HTTP server frameworks like Express (the default) and can optionally use Fastify as well! It supports databases like PostgreSQL, MongoDB, and MySQL. NestJS is heavily influenced by Angular, React, and Vue — while offering dependency injection right out of the box.

For first-time users, we recommend creating a new project with the Nest CLI. First, enter the following command to install the Nest CLI.

npm install -g @nestjs/cli
Enter fullscreen mode Exit fullscreen mode

Next, let’s create a new Nest.js project directory called backend.

mkdir backend
Enter fullscreen mode Exit fullscreen mode

It’s time to populate the directory with the initial core Nest files and supporting modules. From your new backend directory, run Nest’s bootstrapping command. We’ll call our new application link-shortener:

nest new link-shortener

⚡  We will scaffold your app in a few seconds..

CREATE link-shortener/.eslintrc.js (665 bytes)
CREATE link-shortener/.prettierrc (51 bytes)
CREATE link-shortener/README.md (3340 bytes)
CREATE link-shortener/nest-cli.json (118 bytes)
CREATE link-shortener/package.json (1999 bytes)
CREATE link-shortener/tsconfig.build.json (97 bytes)
CREATE link-shortener/tsconfig.json (546 bytes)
CREATE link-shortener/src/app.controller.spec.ts (617 bytes)
CREATE link-shortener/src/app.controller.ts (274 bytes)
CREATE link-shortener/src/app.module.ts (249 bytes)
CREATE link-shortener/src/app.service.ts (142 bytes)
CREATE link-shortener/src/main.ts (208 bytes)
CREATE link-shortener/test/app.e2e-spec.ts (630 bytes)
CREATE link-shortener/test/jest-e2e.json (183 bytes)

? Which package manager would you ❤️  to use? (Use arrow keys)
❯ npm 
  yarn 
  pnpm 


All three packages managers are usable, but we’ll choose npm for the purposes of this walkthrough.


Which package manager would you ❤️  to use? npm
✔ Installation in progress... ☕

🚀  Successfully created project link-shortener
👉  Get started with the following commands:

$ cd link-shortener
$ npm run start


                          Thanks for installing Nest 🙏
                 Please consider donating to our open collective
                        to help us maintain this package.                     
               🍷  Donate: https://opencollective.com/nest
Enter fullscreen mode Exit fullscreen mode

Once the command is executed successfully, it creates a new link-shortener project directory with node modules and a few other boilerplate files. It also creates a new src/ directory populated with several core files as shown in the following directory structure:

tree -L 2 -a
.
└── link-shortener
    ├── dist
    ├── .eslintrc.js
    ├── .gitignore
    ├── nest-cli.json
    ├── node_modules
    ├── package.json
    ├── package-lock.json
    ├── .prettierrc
    ├── README.md
    ├── src
    ├── test
    ├── tsconfig.build.json
    └── tsconfig.json

5 directories, 9 files
Enter fullscreen mode Exit fullscreen mode

Let’s look at the core files ending with .ts (TypeScript) under /src directory:

src % tree
.
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
└── main.ts

0 directories, 5 files
Enter fullscreen mode Exit fullscreen mode

Nest embraces modularity. Accordingly, two of the most important Nest app components are controllers and providers. Controllers determine how you handle incoming requests. They’re responsible for accepting incoming requests, performing some kind of operation, and returning the response. Meanwhile, providers are extra classes which you can inject into the controllers or to certain providers. This grants various supplemental functionality. We always recommend reading up on providers and controllers to better understand how they work.

The app.module.ts is the root module of the application and bundles up a couple of controllers and providers that the controller uses.

cat app.module.ts  
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';


@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

As shown in the above file, AppModule is just an empty class. Nest’s @Module decorator is responsible for providing the config that lets Nest build a functional application from it.

First, app.controller.ts exports a basic controller with a single route. The app.controller.spec.ts is the unit test for the controller. Second, app.service.ts is a basic service with a single method. Third, main.ts is the entry file of the application. It bootstraps the application by calling NestFactory.create, then starts the new application by having it listen for inbound HTTP requests on port 3000.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap(); 
Enter fullscreen mode Exit fullscreen mode

Click here to read the complete blog

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .