MS-4/5/6 글을 통해 Gateway의 공통 기능 구현을 위한 설정을 적용한다.
- Login 할때 사용자 정보는 ORM 기반으로 처리한다.
- 인증을 JWT 기반으로 처리한다.
- Login 화면을 React 기반 구현한다.
NestJS에 Prisma ORM 설정
gateway-api의 공통 기능은 다음과 같고, JWT처리를 위한 사용자 정보 조회를 위해 Prisma ORM을 적용한다. Micro Service도 Prisma를 사용할 것이다.
- api gateway: TCP 통신으로 micro service의 API를 연결한다.
- http server: gateway의 공통 기능중 Login을 서비스한다.
- reverse proxy: Login이 성공하면 dashboard micro service로 이동한다. (configuration, back-office)
- auth server: JWT 기반으로 token을 발행하고, 요청에 대한 모든 Authorization(인가, 권한)을 체크한다.
Step-1) 설치 및 환경 설정
auth server 기능에서 사용자 정보 데이터처리를 위해 ORM으로 Prisma를 사용을 위해 패키지를 (v3.1.1) 설치한다.
$> yarn add -D prisma
$> yarn add @prisma/client
$> yarn add -D ts-node
전체 애플리케이션을 위한 초기 prisma 환경을 생성한다.
$> npx prisma init
✔ Your Prisma schema was created at prisma/schema.prisma
You can now open it in your favorite editor.
Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver (Preview) or mongodb (Preview).
3. Run prisma db pull to turn your database schema into a Prisma schema.
4. Run prisma generate to generate the Prisma Client. You can then start querying your database.
More information in our documentation:
https://pris.ly/d/getting-started
자동 생성된 .env 파일에 설정을 추가한다.
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server (Preview) and MongoDB (Preview).
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
#DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
# POSTGRES
POSTGRES_USER=iot
POSTGRES_PASSWORD=1
POSTGRES_DB=rnm-stack
# Nest run locally
DB_HOST=localhost
# Nest run in docker, change host to database container name
# DB_HOST=postgres
DB_PORT=5432
DB_SCHEMA=public
# Prisma database connection
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:${DB_PORT}/${POSTGRES_DB}?schema=${DB_SCHEMA}&sslmode=prefer
VS Code의 extension을 설치한다.
Step-2) schema.prisma 설정
VSCode extension이 설치되면 schema.prisma의 내용이 다음과 같이 highlighting된다.
schema.prisma 파일 안에 Prisma 방식의 스키마를 정의한다.
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
// previewFeatures = []
}
// generator dbml {
// provider = "prisma-dbml-generator"
// }
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
password String
firstname String?
lastname String?
posts Post[]
role Role
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published Boolean
title String
content String?
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
enum Role {
ADMIN
MANAGER
USER
}
schema.prisma를 통해 Migrate SQL과 Prisma Client 파일을 자동 생성한다. Prisma Client 파일은 구현 코드에서 사용된다. (참조)
Step-3) schema 설정을 통해 sql 생성하기
명령을 수행하면 prisma/migrations sql이 자동 실행된다. 생성된 sql을 통해 table schema를 업데이트한다. 변경점이 있으면 날짜별로 update 할 수 있는 table schema가 자동으로 생성된다.
$> npx prisma migrate dev --create-only --name=iot
또한 DB Schema에 _prisma_migrations 테이블이 자동생성된다.
테이블을 자동 생성하고 싶다. prisma db push 명령을 사용한다. (참조)
$> npx prisma db push
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "rnm-stack", schema "public" at "localhost:5432"
🚀 Your database is now in sync with your schema. Done in 77ms
✔ Generated Prisma Client (3.1.1) to ./node_modules/@prisma/client in 61ms
Step-4) Prisma Studio 사용하기
prisma는 내장 웹기반 studio를 제공한다. 테이블을 선택하여 조작할 수 있다.
$> npx prisma studio
NestJS 에서 PrismaClient 사용하기
Step-1) PrismaClient 생성
schema에 생성되었으면 다음으로 코드에서 Prisma 접근을 위해 PrismaClient를 생성해야 한다. (참조)
- "npx prisma migrate dev" 명령으로 수행할 경우는 "npx prisma generate"이 필요없다.
- "npx prisma migrate dev --create-only" 일 경우만 수행한다.
- schema.prisma 변경시 마다 다시 실행해 주어야 한다. (참조)
$> npx prisma generate
✔ Generated Prisma Client (3.1.1) to ./node_modules/@prisma/client in 181ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client
```
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
```
prisma client는 기본적으로 node_modules/.prisma/client 폴더 밑에 생성된다.
Step-2) schema.prisma가 변경이 발생할 경우
이제 "PrismaClient"를 import해서 사용할 수 있는 상태가 되었다. 만일 테이블 변경이 발생한다면 아래와 같이 수행한다.
- schema.prisma 파일 내역 수정
- "npx prisma migrate" 명령 실행
- migrations 폴더에 있는 migration sql을 database에 적용한다.
Step-3) NestJS 서비스 생성
사용자 정보는 공통이므로 libs/domain 에 생성한다. (참조)
- libs/shared/src/lib밑으로 prisma 폴더를 생성하고, prisma-client.service.ts파일을 생성한다.
- index.ts에 export를 추가한다.
// prisma-client.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'
import { PrismaClient } from '@prisma/client'
@Injectable()
export class PrismaClientService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect()
}
async onModuleDestroy() {
await this.$disconnect()
}
}
// index.ts
export * from './lib/configuration/config.model';
export * from './lib/configuration/config.service';
export * from './lib/prisma/prisma-client.service';
apps/gateway/api/src/app/app.module.ts에 PrismaClientService를 추가한다.
// /apps/gateway/api/src/app/app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { GatewayApiAppService } from '@rnm/domain';
import { PrismaClientService } from '@rnm/shared'; <== 요기
import { AppController } from './app.controller';
import { DashboardModule } from './dashboard/dashboard.module';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, 'public'),
exclude: [
'/api/gateway*', '/api/dashboard*',
'/dashboard*', '/configuration*', '/back-office*'
],
}),
DashboardModule
],
controllers: [AppController],
providers: [GatewayApiAppService, PrismaClientService] <== 요기
})
export class AppModule { }
gateway/api/src/app/app.controller.ts에 테스트 코드로 POST로 user를 생성하는 코드를 작성한다.
// apps/gateway/api/src/app/app.controller.ts
import { Body, Controller, Get, Post } from '@nestjs/common';
import { GatewayApiAppService } from '@rnm/domain';
import { PrismaClientService } from '@rnm/shared';
import { Role, User as UserModel } from '@prisma/client';
@Controller('api/gateway')
export class AppController {
constructor(
private readonly appService: GatewayApiAppService,
private readonly dbService: PrismaClientService
) { }
@Get()
getData() {
return this.appService.getData();
}
@Post('user')
async createUser(@Body() userData: {
email: string,
password: string,
firstname: string,
lastname; string,
role: Role
}): Promise<UserModel> {
const { email, password, firstname, lastname, role } = userData;
return this.dbService.user.create({
data: {
email,
password,
firstname,
lastname,
role: !role ? Role.USER : role
}
});
}
}
VSCode에서 Debug창에서 Gateway를 실행하고, 디버깅을 한다.
Postman을 실행하여 User 를 생성해 본다.
- 새로운 Request를 만들고 POST를 선택
- Body에 JSON 타입을 선택
- request 값을 넣고, http://localhost:8000/api/gateway/user 호출
DB툴로 User insert가 되었는지 확인 또는 prisma studio에서 확인
소스: https://github.com/ysyun/rnm-stack/releases/tag/ms-4
<참조>
- Primsa on NestJS 기반 개발
- Prisma Migrate 순서
https://www.prisma.io/blog/prisma-migrate-ga-b5eno5g08d0b
- Primsa, JWT on NestJS StartKit
https://github.com/fivethree-team/nestjs-prisma-starter
- Prisma의 다양한 DB 예제
'React > Architecture' 카테고리의 다른 글
[MS-6] NestJS의 JWT 기반 Auth Server 환경구축 (0) | 2021.09.27 |
---|---|
[MS-5] NestJS에 TypeORM 사용하기 (0) | 2021.09.27 |
[MS-3] Gateway와 Micro Service간 디버깅 환경 구축 (0) | 2021.09.23 |
[MS-2] React & Nest 기반 애플리케이션 및 Micro Service 통신 설정 (0) | 2021.09.20 |
[MS-1] Micro Service 환경 구축 (0) | 2021.09.20 |