10 Minutes from First Line of Code to Live Deployment: A Super Fast Nest.js Blog Course


Cover

This is a super fast course on Nest.js. In this tutorial, we will build a blog from the first line of code to deployment in just a few simple steps, taking less than 10 minutes.

The reason it’s so fast is that this tutorial won’t delve into detailed explanations of the process. Instead, it will guide you directly to build a finished product. I believe that learning a framework is faster by modifying an existing project to fit your own needs.

This blog consists of 3 functional modules, representing a common technology stack for a pure Node.js backend project:

  • Nest.js
  • PostgreSQL, as the database
  • ejs, for rendering pages

Without further ado, let’s get started:



1. Initialize the Project

Nest.js projects rely heavily on the CLI tool for project management. First, let’s install the Nest.js CLI.

npm i -g @nestjs/cli
Enter fullscreen mode

Exit fullscreen mode

Use the CLI to create a new project.

nest new personal-blog
Enter fullscreen mode

Exit fullscreen mode

This will create a new folder named personal-blog and install all the necessary dependencies. Open this directory in your favorite editor to officially start editing.



2. Connect to the PostgreSQL Database

Next, we will integrate a PostgreSQL database. Following the official recommendation, we’ll use TypeORM as the ORM. The role of an ORM is to integrate the database into the code.



Install Dependencies

npm install @nestjs/typeorm typeorm pg
Enter fullscreen mode

Exit fullscreen mode

  • @nestjs/typeorm: The official Nest.js module for TypeORM, adapting TypeORM for Nest.js.
  • typeorm: The TypeORM library itself.
  • pg: The Node.js driver for PostgreSQL, enabling Node.js to read and write to PostgreSQL.



Set up the Database

To speed up the tutorial, we will skip the step of installing and setting up a database locally. Instead, we’ll provision an online database directly.

We can create a free database with one click on Leapcell.

Leapcell

After registering an account on the website, click “Create Database”.

ImageP1

Enter a Database name, select a deployment region, and you can create the PostgreSQL database.

On the new page that appears, you will find the information needed to connect to the database. A control panel is provided at the bottom, allowing you to read and modify the database directly on the webpage.

ImageP2



Configure the Database Connection

Open the src/app.module.ts file and import TypeOrmModule.

Fill in the connection information using the database configuration from Leapcell. Note that sslMode must be set to true, otherwise, the connection will fail.

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'your_leapcell_host', // Replace with your Leapcell host
      port: 5432,
      username: 'your_postgres_username', // Replace with your PostgreSQL username
      password: 'your_postgres_password', // Replace with your PostgreSQL password
      database: 'personal_blog_db', // Replace with your database name
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true, // Set to true in development, it automatically syncs the database schema
      ssl: true, // Required for services like Leapcell
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode

Exit fullscreen mode



Create the Posts Module

Next, let’s create a module to manage blog posts.

You can use the Nest CLI to quickly generate the required files:

nest generate module posts
nest generate controller posts
nest generate service posts
Enter fullscreen mode

Exit fullscreen mode

After that, we need to create the Post entity file to connect it with the database. In the src/posts directory, create a file named post.entity.ts:

// src/posts/post.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm';

@Entity()
export class Post {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column('text')
  content: string;

  @CreateDateColumn()
  createdAt: Date;
}
Enter fullscreen mode

Exit fullscreen mode

Next, we need to connect to the database.

Register TypeOrmModule in PostsModule: open src/posts/posts.module.ts and import TypeOrmModule.forFeature([Post]).

// src/posts/posts.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PostsController } from './posts.controller';
import { PostsService } from './posts.service';
import { Post } from './post.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Post])],
  controllers: [PostsController],
  providers: [PostsService],
})
export class PostsModule {}
Enter fullscreen mode

Exit fullscreen mode

Go to the Database details page on Leapcell and execute the following command in the web editor to generate the corresponding table.

CREATE TABLE "post" (
    "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    "title" VARCHAR NOT NULL,
    "content" TEXT NOT NULL,
    "createdAt" TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Enter fullscreen mode

Exit fullscreen mode

Finally, we need to create the PostsService. The PostsService will be responsible for handling all business logic related to posts. Open src/posts/posts.service.ts and add the following code:

// src/posts/posts.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Post } from './post.entity';

@Injectable()
export class PostsService {
  constructor(
    @InjectRepository(Post)
    private postsRepository: Repository<Post>
  ) {}

  findAll(): Promise<Post[]> {
    return this.postsRepository.find({
      order: {
        createdAt: 'DESC',
      },
    });
  }

  findOne(id: string): Promise<Post> {
    return this.postsRepository.findOneBy({ id });
  }

  async create(post: Partial<Post>): Promise<Post> {
    const newPost = this.postsRepository.create(post);
    return this.postsRepository.save(newPost);
  }
}
Enter fullscreen mode

Exit fullscreen mode



Set Up EJS for Page Rendering

Now, we’ll set up EJS so that we can render dynamic HTML pages.



Install Dependencies

npm install ejs
Enter fullscreen mode

Exit fullscreen mode



Integrate the View Engine

Open the src/main.ts file and change it to the following:

// src/main.ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('ejs');

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode

Exit fullscreen mode

In the project root directory (at the same level as src), create views and public folders:

- personal-blog
    - src
    - views
    - public
Enter fullscreen mode

Exit fullscreen mode



Implement the Frontend Pages

Create the following files in the views folder:

  • _header.ejs (Reusable header)
  </span>
   lang="en">
    
       charset="UTF-8" />
       name="viewport" content="width=device-width, initial-scale=1.0" />
      <%= title %>
       rel="stylesheet" href="/css/style.css" />
    
    
      
href="/posts/new" class="new-post-btn">New Post
Enter fullscreen mode

Exit fullscreen mode

  • _footer.ejs (Reusable footer)



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *