오늘은 별다른 것보단 과제 프로젝트 진행하는 데에 대부분의 시간을 들였다.
다음이 작업 내역이다.
Prisma Modeling으로 DB 모델 설계
미들웨어 구현: 로깅, 인증, 에러 핸들러
라우팅과 API 구현: users, characters, items (items 진행 중)
현재까지 구현한 내용까지는 에러 캐치와 리팩토링을 마친 상황으로, insomnia를 통한 api client 테스팅도 정상 작동함을 확인한 상태이다.
어려웠던 부분이라기 보다 하나 기억에 남는 점이 있다면,
character 루트 단의 생성 api에 관해서,
characters 테이블의 인스턴스만 생성하는 것이 아니라,
1대1 대응되는 characterStats와 inventory 테이블의 인스턴스도 생성해줘야 하기 때문에
리팩토링하면서 트랜잭션을 통한 처리로 바꿔준 기억이 난다.
router.post('/characters/create', authMiddleware, async (req, res, next) => {
try {
const { user_id } = req.user;
const { character_name, character_type } = req.body;
// validation: character_name : 중복 불가
const isCharNameExist = await prisma.characters.findFirst({
where: {
character_name,
},
});
if (isCharNameExist)
return res.status(409).json({ message: '[Conflict] character_name already exists' });
// type별 캐릭터 스탯 초기화값 가져오기
const initStats = characterStatsInitialValues[character_type];
if (!initStats)
return res.status(400).json({ message: '[Error] failed to initialize characterStat' });
// consistency를 위한 트랜잭션 사용
const newCharacter = await prisma.$transaction(async (trx) => {
// 캐릭터 생성
const tmpCharacter = await trx.characters.create({
data: {
user_id: +user_id,
character_name,
character_type,
},
});
// 대응하는 characterStats 생성과 초기화
await trx.characterStats.create({
data: {
character_id: tmpCharacter.character_id,
...initStats,
},
});
// 대응하는 invnetory 생성과 초기화 .. gold는 default로 설정
await trx.inventory.create({
data: {
character_id: tmpCharacter.character_id,
},
});
return tmpCharacter;
});
// 성공시 반환
return res.status(201).json({
message: '[Created] new character creation completed.',
character_id: newCharacter.character_id,
});
} catch (error) {
next(error);
}
});