일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- koi 2002 중등부 1번
- 그리디
- MongoDB
- ERD
- 백준 28298번
- router
- MySQL
- ucpc 2024 예선 e번
- JavaScript
- branch
- ccw 알고리즘
- insomnia
- PROJECT
- 백준 28303번
- ucpc 2023 예선 i번
- string
- 게임 서버 아키텍처
- Next
- pm2
- 백준 2623번
- map
- HTTP
- 더 흔한 색칠 타일 문제
- ucpc 2023 예선 d번
- Github
- Express.js
- localstorage
- 자바스크립트
- html5
- Prisma
Archives
- Today
- Total
dh_0e
[Node.js] 강의 내용 개념 정리(8) (Prisma Transaction, express-session) 본문
내일배움캠프/Node.js[숙련]
[Node.js] 강의 내용 개념 정리(8) (Prisma Transaction, express-session)
dh_0e 2024. 5. 28. 20:50Prisma Transaction
- 여러 개의 쿼리를 하나의 트랜잭션으로 수행할 수 있는 Sequential 트랜잭션,
- Prisma가 자체적으로 트랜잭션의 성공과 실패를 관리하는 Interactive 트랜잭션이 존재함
Sequential 트랜잭션
- Prisma의 여러 쿼리를 배열([ ])로 전달받아, 각 쿼리들을 순서대로 실행하는 특징이 있어 여러 작업이 순차적으로 실행되어야 할 때 사용 가능
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Sequential 트랜잭션은 순차적으로 실행됩니다.
// 결과값은 각 쿼리의 순서대로 배열에 담겨 반환됩니다.
const [posts, comments] = await prisma.$transaction([
prisma.posts.findMany(),
prisma.comments.findMany(),
]);
- Raw Query에서도 사용 가능
더보기
Sequential Transaction, Raw Query
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Sequential 트랜잭션은 순차적으로 실행됩니다.
// Raw Quyery를 이용하여, 트랜잭션을 실행할 수 있습니다.
const [users, userInfos] = await prisma.$transaction([
prisma.$queryRaw`SELECT * FROM Users`,
prisma.$queryRaw`SELECT * FROM UserInfos`,
]);
Interactive 트랜잭션
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Prisma의 Interactive 트랜잭션을 실행합니다.
const result = await prisma.$transaction(async (tx) => { // tx를 prisma처럼 사용
// 트랜잭션 내에서 사용자를 생성합니다.
const user = await tx.users.create({
data: {
email: 'testuser@gmail.com',
password: 'aaaa4321',
},
});
// 에러가 발생하여, 트랜잭션 내에서 실행된 모든 쿼리가 롤백됩니다.
throw new Error('트랜잭션 실패!');
return user;
});
- 비즈니스 로직이 성공적으로 완료되면 자체적으로 COMMIT 실행
- 에러가 발생했을 때 자체적으로 ROLLBACK을 실행하여 트랜잭션을 관리
- 트랜잭션 진행 중에도 비즈니스 로직을 처리할 수 있어 복잡한 쿼리 시나리오를 효과적으로 구현할 수 있음
- (자유도가 높음)
Prisma에서 격리 수준을 설정하는 방법
- isolationLevel 옵션을 정의함으로써 설정할 수 있음
import { Prisma } from '@prisma/client';
await prisma.$transaction(
async (tx) => { ... },
{
isolationLevel: Prisma.TransactionIsolationLevel.ReadCommitted,
},
);
UUID(범용 공유 식별자)
UUID(Universally Unique Identifier, 범용 고유 식별자)는 총 4개의 정보를 하이픈(-)으로 구분하여 순차적으로 저장한 데이터 타입이며 시간 정보를 포함하고 있어 생성된 순서대로 정렬이 되는 특징을 가지고 있음
express-session
- Express.js에서 세션(Session) 기능을 쉽게 구현하기 위한 미들웨어
- 위와 같은 복잡한 Cookie-Session 흐름을 미들웨어 하나로 간단하게 구현할 수 있게 해줌
express-session 미들웨어의 구성 요소
- express-session은 아래와 같이 전역 미들웨어로 등록됨
app.use(
expressSession({
secret: 'express-session-secret-key.', // 세션을 암호화하는 비밀 키를 설정
resave: false, // 클라이언트의 요청이 올 때마다 세션을 새롭게 저장할 지 설정, 변경사항이 없어도 다시 저장
saveUninitialized: false, // 세션이 초기화되지 않았을 때 세션을 저장할 지 설정
cookie: {
// 세션 쿠키 설정
maxAge: 1000 * 60 * 60 * 24, // 쿠키의 만료 기간을 1일로 설정합니다.
},
}),
);
- secret
- 세션 ID를 암호화하기 위한 비밀 키
- 클라이언트에게 발급할 세션 ID를 암호화하기 위한 비밀 키 정보
- resave
- 클라이언트의 요청(Request)이 들어올 때마다 세션 정보를 다시 저장할 지 설정함
- 변경사항이 없더라도 true 로 설정하면, 매번 새로운 세션에 저장됨
- saveUninitialized
- req.session에 아무런 정보가 저장이 되지 않더라도 사용자에게 세션 ID를 발급할 지 설정함
- true 로 설정하면, 서버에 접속하는 모든 사용자에게 세션 ID가 발급됨
- cookie.maxAge
- 세션 ID가 저장된 클라이언트의 쿠키 만료 기간을 설정
POST /sessions API 만들기
/** 세션 등록 API **/
app.post('/sessions', (req, res, next) => {
const { userId } = req.body;
// 클라이언트에게 전달받은 userId를 세션에 저장합니다.
req.session.userId = userId;
return res.status(200).json({ message: '세션을 설정했습니다.' });
});
- req.session은 클라이언트의 세션 정보를 관리하는데 사용되는 객체
- 클라이언트의 요청이 들어오면 req.session.<property 명>에 원하는 정보 저장
GET /sessions API 만들기
/** 세션 조회 API **/
app.get('/sessions', (req, res, next) => {
return res.status(200).json({
message: '세션을 조회했습니다.',
session: req.session.userId ?? null, // 세션에 저장된 usrId를 조회합니다.
});
});
- express-session은 클라이언트가 전달한 쿠키의 세션 ID를 바탕으로 req.session에서 정보를 조회
- 클라이언트가 제공한 세션 ID가 없을 경우 Null 반환
- 기존 JWT를 이용한 쿠키를 클라이언트에게 전달하는 것보다 더욱 편리하게 구현할 수 있다는 장점이 있음
- 서버가 종료되면 express-session의 정보 또한 사라지는 인 메모리(In-Memory)방식이라는 단점이 있음
express-mysql-session
- express-session의 세션 정보를 MySQL에 저장할 수 있도록 도와주는 모듈
- express-session의 인 메모리 방식으로 인한 단점을 해결하기 위해 사용됨
import expressSession from "express-session";
import expressMySQLSession from "express-mysql-session";
const MySQLStorage = expressMySQLSession(expressSession);
const sessionStore = new MySQLStorage({
// 우리가 어떤 MySQL을 사용할 건지
user: "root",
password: "PW 입력",
host: "DB의 엔드 포인트 입력",
port: 3306,
database: "notice_board",
expiration: 1000 * 60 * 60 * 24,
createDatabaseTable: true,
});
app.use(
expressSession({
secret: "customized_secret_key",
resave: false,
saveUninitialized: false,
store: sessionStore,
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 1일 동안 사용 가능
},
})
);
- express-mysql-session 또한 세션 ID로 정보를 조회할 때마다 MySQL의 조회 쿼리를 매번 실행한다는 문제점이 존재
- 이에 대한 해결방법은 다시 JWT 쿠키를 이용하는 것 or MySQL 대신 외부 세션 스토리지를 캐시 메모리 데이터베이스인 Redis로 변경하는 것
dotenv
Node.js를 위한 환경 변수 관리 모듈로 .env파일을 통해 환경 변수를 process.env에 추가하는 역할을 함
- 라이브러리 설치
yarn add -D dotenv
- 라이브러리 적용
import dotenv from 'dotenv';
// .env 파일을 읽어서 process.env에 추가
dotenv.config();
- 이후 process.env.KEY로 사용 (.env 파일엔 KEY="VALUE" 형식으로 저장)
'내일배움캠프 > Node.js[숙련]' 카테고리의 다른 글
[Node.js] 강의 내용 개념 정리(7) (로그 미들웨어, Transaction) (0) | 2024.05.28 |
---|---|
[Node.js] 강의 내용 개념 정리(6) (Access Token, Refresh Token) (0) | 2024.05.27 |
[Node.js] 강의 내용 개념 정리(5) (인증, 인가, 사용자 인증 미들웨어) (0) | 2024.05.27 |
[Node.js] 강의 내용 개념 정리(4) (JWT) (0) | 2024.05.24 |
[Node.js] 강의 내용 개념 정리(3) (Cookie, Session) (0) | 2024.05.24 |