Loading...
본문 바로가기
👥
총 방문자
📖
0개 이상
총 포스팅
🧑
오늘 방문자 수
📅
0일째
블로그 운영

여러분의 방문을 환영해요! 🎉

다양한 개발 지식을 쉽고 재미있게 알려드리는 블로그가 될게요. 함께 성장해요! 😊

코딩 정보/NestJs

[NestJs] docker를 통해 postgresql 세팅을 해보자

by 꽁이꽁설꽁돌 2025. 1. 8.
728x90
반응형
     

목차

     

     

    프로젝트 생성하기

    nest new 프로젝트 명

     

    그 후 선택한 패키지 매니저로 init을 해주자

    그런데 빨간색 오류가 날 수 있다.

     

     

    당황하지 말고 eslintrc.js의 rule에 다음 코드를 추가해 주자

    endOfLine: 'lf',

     

    docker 설치

    https://www.docker.com/

     

    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

     

    반응형