[nestjs] restapi + prisma 01

in kr •  last year 

출처

PART1 - Building a REST API with NestJS and Prisma

image.png

TR;DR

  • 프로젝트 생성 : npx @nestjs/cli
  • postgresql 인스턴스 생성 : docker-compose
  • schema.prisma
  • seed.ts
  • npx nest generate resource

소개

이 자습서에서는 "Median"(간단한 Medium 클론)이라는 블로그 애플리케이션용 백엔드 REST API를 빌드하는 방법을 배웁니다. 새로운 NestJS 프로젝트를 생성하여 시작합니다. 그런 다음 자체 PostgreSQL 서버를 시작하고 Prisma를 사용하여 연결합니다. 마지막으로 REST API를 빌드하고 Swagger로 문서화합니다.

필요 기술

만약 intelisense 가 정상적으로 잘 동자하지 않는 경우 npm install -g typescript 커맨드를 통해 최신 typescript 를 설치
tsc --version 을 통해 설치된 버전 정보 확인가능

선수지식

  • JavaScript 또는 TypeScript에 대한 기본 지식(선호)
  • NestJS에 대한 기본 지식

개발환경

  • node.js 설치
  • docker 또는 postgresql 설치
  • prisma vscode extension 설치

nestjs 프로젝트 생성하기

npx @nestjs/cli new median
# 생성 후 폴더로 이동
cd median

신규 nestjs 프로젝트 생성 후 구성 된 폴더 구조는 다음과 같습니다.

median
  ├── node_modules
  ├── src
  │   ├── app.controller.spec.ts
  │   ├── app.controller.ts
  │   ├── app.module.ts
  │   ├── app.service.ts
  │   └── main.ts
  ├── test
  │   ├── app.e2e-spec.ts
  │   └── jest-e2e.json
  ├── README.md
  ├── nest-cli.json
  ├── package-lock.json
  ├── package.json
  ├── tsconfig.build.json
  └── tsconfig.json

작업에 필요한 대부분의 파일은 src 폴더 아래에 존재 합니다.

중요한 파일은 다음과 같습니다.

  • src/main.ts : NestJS 애플리케이션의 진입점
  • src/app.module.ts : NestJS 애플리케이션의 루트 모듈
  • src/app.controller.ts : NestJS 애플리케이션의 루트 컨트롤러

아래 커맨드를 통해 app 을 구동 시킬 수 있습니다.

npm run start:dev

http://localhost:3000 으로 접속하면 다음과 같은 화면을 볼 수 있습니다. Hello World!

postgresql 인스턴스 만들기

docker compose 를 사용하여 postgresql 인스턴스를 만들어 보겠습니다.
(사전에 docker desktop 또는 docker compose 설치가 필요 )

touch docker-compose.yml
# docker-compose.yml

version: '3.8'
services:
  postgres:
    image: postgres:13.5
    restart: always
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
    volumes:
      - postgres:/var/lib/postgresql/data
    ports:
      - '5432:5432'

volumes:
  postgres:

docker compose up 명령을 실행하여 postgresql 인스턴스를 실행합니다.

prisma 설정

# prisma cli 설치
npm install -D prisma

# prisma 초기화
# prisma 폴더가 생성되고 schema.prisma 파일이 생성됩니다.
npx prisma init

# .env 파일 생성
touch .env
// .env
DATABASE_URL="postgres://myuser:mypassword@localhost:5432/median-db"

schema.prisma 파일의 주요 설정 정보

  • data source : 데이터베이스 연결 정보
  • generator : prisma client 생성 정보
  • data model : 데이터 모델
// prisma/schema.prisma

model Article {
  id          Int      @id @default(autoincrement())
  title       String   @unique
  description String?
  body        String
  published   Boolean  @default(false)
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

DB 마이그레이션

npx prisma migrate dev --name "init" 커맨드를 입력하여 마이그레이션을 실행합니다.

아래와 같은 절차로 실행됨

  1. 마이그레이션 파일 생성 : sql 파일 생성 ( prisma/migrations/**/migration.sql )
  2. 마이그레이션 실행 : sql 파일 실행
  3. Prisma 클라이언트 생성

초기데이터(seed) 적재

touch prisma/seed.ts

// prisma/seed.ts

import { PrismaClient } from '@prisma/client';

// initialize Prisma Client
const prisma = new PrismaClient();

async function main() {
  // create two dummy articles
  const post1 = await prisma.article.upsert({
    where: { title: 'Prisma Adds Support for MongoDB' },
    update: {},
    create: {
      title: 'Prisma Adds Support for MongoDB',
      body: 'Support for MongoDB has been one of the most requested features since the initial release of...',
      description:
        "We are excited to share that today's Prisma ORM release adds stable support for MongoDB!",
      published: false,
    },
  });

  const post2 = await prisma.article.upsert({
    where: { title: "What's new in Prisma? (Q1/22)" },
    update: {},
    create: {
      title: "What's new in Prisma? (Q1/22)",
      body: 'Our engineers have been working hard, issuing new releases with many improvements...',
      description:
        'Learn about everything in the Prisma ecosystem and community from January to March 2022.',
      published: true,
    },
  });

  console.log({ post1, post2 });
}

// execute the main function
main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(async () => {
    // close Prisma Client at the end
    await prisma.$disconnect();
  });

package.json 파일에 seed 커맨드를 추가합니다.

{
  // ...
  "prisma": {
    "seed": "ts-node prisma/seed.ts"
  }
}

npx prisma db seed 커맨드를 입력하여 초기 데이터를 적재합니다.

prisma 서비스 만들기

npx nest generate module prisma
npx nest generate service prisma
// src/prisma/prisma.service.ts

import { INestApplication, Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient {}

// src/prisma/prisma.module.ts

import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}

swagger 설정

npm install --save @nestjs/swagger swagger-ui-express
// src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

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

  const config = new DocumentBuilder()
    .setTitle('Median')
    .setDescription('The Median API description')
    .setVersion('0.1')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();

npm run start:dev application 재 기동 후 http://localhost:3000/api 링크로 접속하여 swagger ui 를 확인할 수 있습니다.

REST 자원 만들기

nest 명령을 사용하여 손쉽게 REST 자원을 만들 수 있습니다.

# 1. articles
# 2. REST API
# 3. Yes
# 위와 같이 입력하면 src/articles 라는 폴더가 생성되며 기본 정보가 설정된다
npx nest generate resource

npm run start:dev application 재 기동 후 http://localhost:3000/api 링크로 접속면 이전과 달리 articles 관련 CRUD 관련 api 가 노출되는 것을 확인할 수 있다.

SwaggerModule 은 @Body, @Query, @Param 등의 데코레이터를 사용하여 자동으로 문서를 생성한다.


to be continued ...

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

image.png

Upvoted! Thank you for supporting witness @jswit.