목차
프로젝트 생성하기
nest new 프로젝트 명
그 후 선택한 패키지 매니저로 init을 해주자
그런데 빨간색 오류가 날 수 있다.
당황하지 말고 eslintrc.js의 rule에 다음 코드를 추가해 주자
endOfLine: 'lf',
docker 설치
Docker: Accelerated Container Application Development
Docker is a platform designed to help developers build, share, and run container applications. We handle the tedious setup, so you can focus on the code.
www.docker.com
docker-compose.yaml 파일 만들어 주기
services:
postgres:
image: postgres:15
restart: always
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
간단히 설명하면 다음과 같다.
- services: docker compose에서 여러개의 서비스를 정의하게 해준다.
- postgres: 서비스 이름으로 우리가 사용할 postgreSQL 데이터 베이스이다.
- image: postgres:15 : 사용될 docker 이미지를 지정한 것으로 15버전을 사용할 것이라는 것을 명시
- restart: always: docker 컨테이너가 종료되거나 서버가 재시작될 때 컨테이너를 자동으로 재시작하도록 설정
- volumes: ./postgres-data:/var/lib/postgresql/data: 로컬 시스템의 디렉터리를 Docker 컨테이너의 디렉터리와 연결
- ports: "5432:5432": 호스트 시스템의 5432 포트를 컨테이너의 5432 포트와 연결한다.
- environment: Docker 컨테이너 내에서 사용할 환경 변수를 설정한다.
docker-compose up
그 이후의 위의 명령어를 실행하자
그러면 다음과 같이 터미널이 보인다. postgres 가상환경이 잘 설정되었다.
extension 깔아주기 postgreSQL
5.f1을 통해 익스텐션 실행
이 익스텐션을 사용하는 이유는 데이터베이스를 눈으로 확인하기 쉽게 만든다.
extension을 postgresql과 연결하기
아래 스크린샷을 통해 천천히 따라해보자
그러면 이렇게 생긴 것을 볼 수 있다.
typeorm 패키지 설치
그 후 다음 명령어를 통해 typeorm을 깔아준다.
yarn add @nestjs/typeorm typeorm pg
entity파일 만들어 주기
임시로 db를 만들어 주자 id, author, title, content, likeCount, commentCount 로 예시를 만들었다.
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class PostsModel {
//절대적으로 겹치지 않는 칼럼 생성
@PrimaryGeneratedColumn()
id: number;
@Column()
author: string;
@Column()
title: string;
@Column()
content: string;
@Column()
likeCount: number;
@Column()
commentCount: number;
}
템플릿 생성
CRUD(Create, Read, Update, Delete) 작업을 수행하는 데 필요한 모든 파일을 생성하는 템플릿 생성하기.
nest g resource
기본적인 crud 예시 코드로 이루어진 posts.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PostsModel } from './entities/posts.entity';
export interface PostModel {
id: number;
author: string;
title: string;
content: string;
likeCount: number;
commentCount: number;
}
@Injectable()
export class PostsService {
//이 부분을 통해 레포를 연결할 수 있다. 매우 중요
constructor(
@InjectRepository(PostsModel)
private readonly postsRepository: Repository<PostsModel>,
) {}
async getAllPosts() {
return this.postsRepository.find();
}
async getPostById(id: number) {
//await 필수 -> 레포 함수는 비동기
const post = await this.postsRepository.findOne({
where: {
id,
},
});
if (!post) {
throw new NotFoundException();
}
return post;
}
async createPost(author: string, title: string, content: string) {
// 1) create -> 저장할 객체를 생성한다 자동완성을 제공하기 때문에
// 2) save method -> 객체를 저장한다
const post = this.postsRepository.create({
author,
title,
content,
likeCount: 0,
commentCount: 0,
});
const newPost = await this.postsRepository.save(post);
return newPost;
}
async updatePost(
postId: number,
author?: string,
title?: string,
content?: string,
) {
//save의 기능
// 만약에 데이터가 존재하지 않는다면 (id 기준으로) 새로 생성
// 만약에 데이터가 존재하면 존재하던 값을 업데이트 한다
const post = await this.postsRepository.findOne({
where: {
id: postId,
},
});
if (!post) {
throw new NotFoundException();
}
if (author) {
post.author = author;
}
if (title) {
post.title = title;
}
if (content) {
post.content = content;
}
const newPost = await this.postsRepository.save(post);
return newPost;
}
async deletePost(postId: number) {
const post = await this.postsRepository.findOne({
where: {
id: postId,
},
});
if (!post) {
throw new NotFoundException();
}
await this.postsRepository.delete(postId);
return postId;
}
}
기본적인 crud 예시 코드로 이루어진 posts.controll.ts
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { PostsService } from './posts.service';
// GET / post
// 모든 post를 다 가져온다.
// GET / posts/:id
// id에 해당되는 post를 가져온다.
// POST / posts
// POST를 생성한다
// PUT / post/:id
// id에 해당되는 POST를 변경한다
// DELETE / posts/:id
// id에 해당되는 POST를 삭제한다.
//요청을 받고 정확하게 함수로 라우팅해주는 역할
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
@Get()
getPosts() {
return this.postsService.getAllPosts();
}
@Get('/:id')
getPost(@Param('id') id: string) {
return this.postsService.getPostById(+id);
}
@Post()
postPosts(
@Body('author') author: string,
@Body('title') title: string,
@Body('content') content: string,
) {
return this.postsService.createPost(author, title, content);
}
@Put(':id')
putPost(
@Param('id') id: string,
@Body('author') author?: string,
@Body('title') title?: string,
@Body('content') content?: string,
) {
return this.postsService.updatePost(+id, author, title, content);
}
@Delete(':id')
deletePost(@Param('id') id: string) {
return this.postsService.deletePost(+id);
}
}
//주로 사용되는 exception
// BadRequestException
// UnauthorizedException
// NotFoundException
// ForbiddenException
레포지토리와 모델의 연결 코드 posts.module.ts
아래와 같은 코드가 있어야 데이터베이스를 연결할 수 있다.
import { Module } from '@nestjs/common';
import { PostsService } from './posts.service';
import { PostsController } from './posts.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PostsModel } from './entities/posts.entity';
//레포지토리는 모델을 다룰 수 있게 해주는 클래스
@Module({
imports: [
TypeOrmModule.forFeature([
PostsModel,
])
],
controllers: [PostsController],
providers: [PostsService],
})
export class PostsModule {}
만든 entity를 app.module.ts에 주입하기
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModel } from './entities/posts.entity';
import { PostsModule } from './posts/posts.module';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
PostsModule,
TypeOrmModule.forRoot({
type: 'postgres', // 사용할 데이터베이스 유형 (PostgreSQL)
host: '127.0.0.1', // 데이터베이스 호스트
port: 5432, // 데이터베이스 포트 (PostgreSQL 기본 포트)
username: 'postgres', // 데이터베이스 사용자 이름
password: 'postgres', // 데이터베이스 비밀번호
database: 'postgres', // 사용할 데이터베이스 이름
entities: [
PostsModel, // 엔티티 목록 (이 경우, PostsModel 엔티티)
],
synchronize: true, // 애플리케이션 실행 시 데이터베이스 스키마를 자동으로 동기화
})
],
controllers: [AppController], // 컨트롤러 정의
providers: [AppService], // 서비스 정의
})
export class AppModule {}
성공적으로 만들어진 모습
이런식으로 연결이 잘 된것을 볼 수 있다.
[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core 강의 | 코드팩토리 -
코드팩토리 | 자바스크립트, 타입스크립트 다음은 백엔드 개발! NestJS를 이용한 REST API 백엔드 개발, Socket IO 개발 및 배포를 할 수 있게 됩니다., 백엔드가 처음이어도 누구나 OK! 트렌디한 NestJS로
www.inflearn.com
'코딩 정보 > NestJs' 카테고리의 다른 글
[NestJs] 토큰 가드를 구현해보자 (0) | 2025.01.24 |
---|---|
[NestJs] 파이프에 대해 알아보자 (0) | 2025.01.21 |
[NestJs] 로그인 기능을 구현해 보자 (0) | 2025.01.21 |
[NestJs][typeorm] 기본적인 관계형 database를 만들어 보자 (0) | 2025.01.12 |
[NestJs] 기본적인 restful api 만들어 보기 (1) | 2025.01.06 |