TIL 44일차 - API 살짝 수정, 3계층 아키텍처 구현 연습

박찬웅·2023년 3월 21일
0

항해99

목록 보기
49/105

23년 3월 21일

배운 것

오늘은 내가 틀린 거 약간의 오탈자만 수정했고, 그리고 프론트앤드 분들이랑 코드를 맞춰보고 수정하는 작업을 하였다. 그리고 시간이 남아서 저번 주특기 심화주차때 끝내 시도 못해봤던 3계층 아키텍처 연습을 하였다.

시도 한 것

오늘 같은 백앤드 팀원들이랑 의논한거는 그렇게 많은 것은 없었다. 미세한 차이만 수정한거라 사실상 어제가 거의 끝으로 대부분 API 구현은 끝났다. 그래도 가끔씩 프론트앤드분들이 중간에 막혔을 때 우리도 잠깐 와서 간단한 수정만 하는 것만 대부분이였고, 그래서 백앤드 분들은 시간이 남아 프론트앤드 분들이 계속해서 작업 마무리 할 때까지, 각자 추가적으로 하고 싶은 공부 하기로 하였다. 그래서 나는 저번 심화주차때 LV5를 시도를 못했는데, 한번 3계층 아키택쳐로 구현하는 연습을 해 보았다. 당연히 기존 프로젝트에단 안하고 별도로 내꺼에다 따로 작성을 하였다.

우선 기존 라우터 하나에서 모든 API 코드를 작성을 하였다. 꼭 프로젝트때 3계층으로 해야 되는 것은 아니지만, 나중에 실전프로젝트 할 때에는 아마 거의 할 것이기에 뒤늦게라도 따라가기 위해서 시도를 하였다.
근데 중간에 프론트앤드분들이 자주 질문한 타이밍이 많아서, 3계층 아키텍쳐 구현 연습은 그렇게 많이 한 편은 아니다. 그래서 오늘은 회원가입 API만 3계층으로 분리하는 작업을 가졌다.

먼저 기존 회원가입 라우터에서는 다음과 같이 바꿨다. lv4에서 했던것에서 약간 데이터베이스 설정도 변경을 해서 lv4랑은 조금 차이는 난다.

const express = require("express");
const router = express.Router();

const UsersController = require('../controllers/users.controller');
const usersController = new UsersController();

router.post('/', usersController.createUser);

module.exports = router;

보면 아주 기본 라우터 연결 뼈대만 남은걸 볼 수 있고 세부적인 것들은 컨트롤러에서 작업을 하게 된다.

const { Users } = require('../models');

const UserService = require('../services/users.service');

    class UsersController {
        userService = new UserService(); 

        createUser = async (req, res, next) => {
            try {
                const { userId, nickname, password, confirm } = req.body;
                // userId 동일한 데이터가 있는지 확인하기 위해 가져온다.
                const existsUsers = await Users.findOne({ where : {userId : userId}}); // mysql은 where절을 사용해야함
                if (!userId.match(/^[a-zA-Z0-9]{4,20}$/)) {
                    res.status(400).json({ errorMessage: "아이디 형식이 올바르지 않습니다."})
                    return;
                }
                // 이미 해당 닉네임이 등록 되었을 때
                if (existsUsers) {
                // NOTE: 보안을 위해 인증 메세지는 자세히 설명하지 않습니다.
                    res.status(412).json({errorMessage: "이미 등록된 아이디입니다."});
                    return;
                }
                if (!nickname) {
                    res.status(400).json({ errorMessage: "닉네임 형식이 올바르지 않습니다."})
                    return;
                }
                if (!password.match(/^[a-zA-Z0-9]{4,20}$/)) {
                    res.status(400).json({ errorMessage: "비밀번호 형식이 올바르지 않습니다."})
                    return;
                }
                if (password.includes(nickname)) {
                    res.status(400).json({ 
                        errorMessage: "패스워드에 닉네임이 포함되어 있습니다." 
                    });
                    return;
                }
                if ( password !== confirm ) {
                    res.status(400).json({ errorMessage: "비밀번호와 비밀번호 확인이 일치하지 않습니다."})
                    return;
                }
                await this.userService.createUser(userId, nickname, password);
                res.status(201).json({ message: "회원 가입에 성공하였습니다."});
            } catch(err) {
                console.log(err);
                res.status(400).json({ errorMessage: "회원 가입에 실패했습니다."});
                return;
            }
        }
    }
    
module.exports = UsersController;

다음 컨트롤러 계층에서 아이디, 닉네임, 패스워드, 패스워드 확인를 req.body으로 받아서 성공하는 처리를 하였다. 그리고 여기서 대부분 에러 핸들링을 처리를 하였다.

const UserRepository = require('../repositories/users.repository');

class UserService {
    userRepository = new UserRepository();

    createUser = async (userId, nickname, password) => {
        const createUserData = await this.userRepository.createUser(
            userId,
            nickname,
            password,
        );

        return {
            userId: createUserData.userId,
            nickname: createUserData.nickname,
            password: createUserData.password,
            createdAt: createUserData.createdAt,
            updatedAt: createUserData.updatedAt,
        };
    };
}

module.exports = UserService;

다음 서비스 계층에서 적은 코드이다. 해당 코드는 저장소를 생성해서 해당 데이터를 저장소로 전달을 한다, 그리고 데이터를 가져 온 것을 다음과 같이 반환을 해준다.

const { Users } = require('../models');

class UserRepository {
    createUser = async (userId, nickname, password) => {
        const createUserData = await Users.create({
            userId,
            nickname,
            password,
        });
    
        return createUserData;
    };
}

module.exports = UserRepository;

마지막으로 저장소 계층을 적은 코드이다. 해동코드는 Users 테이블에 값을 생성하는 코드를 작성을 하였다.

이렇게 회원가입 API까지 마무리 하고 원래는 로그인까지 하려고 했으나 회원가입과 다르게 로그인은 POST로 보내는데 데이터베이스를 바꾸는것이 아니라서 여기서 막힌 상태라 이 부분은 내일 팀원분들에게 질문 요청을 할 계획이다.

해결

오늘 부로 백앤드 API는 마무리 하였고, 남는 시간동안 3계층 아키텍처로 구현한 회원가입 API를 작성하였다.

알게 된 점

오늘은 상대적으로 많이 한 건 없었다. 남은기간동안에는 프론트앤드분들이 우리가 작성한 API를 받아서 UI를 작업하고 CSS를 작업해야 하기 때문에 확실히 프론트앤드분들이 많이 고생한 느낌을 받았다. 이번 기수에 프론트앤드분들이 유독 적어서 기능을 많이 구현하고 싶어도 프론트앤드 두 분이 빠르게 끝내는것은 무리기에 프론트앤드분들이 끝내는동안 각자 부족했던 부분을 공부를 하기 시작하였고 나는 3계층 아키텍쳐 연습을 하였다. 아예 못하는 것보다는 그래도 조금이라도 하는 것이 더 좋기 때문에 늦은 오후부터 개념을 정리하고 로그인 API는 구현하는데에는 성공하였다. 다만 로그인 API는 구현을 아직 못했는데, 로그인도 같은 POST 요청이지만 회원가입과 다르게 데이터를 바꾸는 것이 아니라 토큰을 얻는 방식이라 좀 다른 방식의 3계층 분리가 필요한데 아직 이 부분을 제대로 터득을 못 한 것 같다. 그래서 이 부분은 내일 팀원들한테 요청을 해볼 생각이다.

앞으로 할 일

계속해서 프론트앤드분들이 구현하는 동안 API에 문제가 발생하면 수정을 하는 작업을 하고, 나는 계속해서 3계층 아키텍쳐 연습을 해 볼 생각이다.

profile
향해 13기 node.js 백앤드

0개의 댓글