[Node.js_4기] TIL - 개인과제 정렬기능 리팩토링(24/02/05)

2024. 2. 5. 18:50공부/내배캠 TIL

목차

 

1. 문제

2. 시도

3. 결과

4. 배운점

명세서는 작성했으나, 연결되지 않아 웹에 게시. 배포는 하지 못했습니다. 다음 TIL부터는 선택 요구사항 구현에 대해 쓸것 같습니다.

 

1. 문제 

개인과제가 끝나고, 과제 해설 영상을 통한 그로우업 시간을 가지고 있습니다.(주말은 쉬었습니다.)

 

 

 

<이력서 전체 목록 검색 API>

router.get('/resumes', async (req, res, next) => {
    try {
    //validation & path handler
        const { orderKey, orderValue } = req.query;
        let orderBy = { createdAt: 'desc' };

        if (orderKey && orderValue) {
            const validOrderValues = ['asc', 'desc'];

            if (validOrderValues.includes(orderValue.toLowerCase())) {
                orderBy[orderKey] = orderValue.toLowerCase();
            }
        }

        const resumes = await prisma.resumes.findMany({
            select: {
                resumeId: true,
                title: true,
                content: true,
                status: true,
                createdAt: true,
                updatedAt: true,
                userId: true,
                auth: true
            },
            orderBy: orderBy,
        });

        return res.status(200).json({ data: resumes });
    } catch (error) {
        console.error('이력서를 가져오는 중 오류 발생:', error);
        return res.status(500).json({ message: '내부 서버 오류' });
    }
});

제출 당시에 정렬 기능을 제대로 구현하지 못했습니다...

(어째서 당시에 req.query를 사용했는지는 지금와서는 기억나지 않는다는 말 밖에는 할 수 없습니다...)

하지만 실제로 로컬환경에서 테스트할 때는

{
	"orderKey":"resumeId",
  	"orderValue":"asc"
}

와 같은 형태의 body 데이터로 정렬을 요청하고 있기 때문에 문제가 발생하였습니다.

즉, 아예 query를 입력하지 않았기 때문에 당연하게 default값으로 response하고 있었습니다.

 

또, validation부분에서 유효성 검사와 경로 처리가 동시에 시행되어 이해와 유지관리가 쉽지만,

두 처리의 결합으로 인해 여러 경로에서의 유효성 검사가 필요한 경우, 문제가 발생할 수 있습니다.

 

2. 시도 

router.get('/resumes', async (req, res, next) => {
    try {
        const { orderKey, orderValue } = req.body;

		//validation
        if (!orderKey || !orderValue) {
            return res.status(400).json({
                success: false,
                message: 'orderKey 또는 orderValue가 제공되지 않았습니다.'
            });
        }

        if (!['resumeId', 'status'].includes(orderKey)) {
            return res.status(400).json({
                success: false,
                message: 'orderKey가 올바르지 않습니다.'
            });
        }

        if (!['asc', 'desc'].includes(orderValue.toLowerCase())) {
            return res.status(400).json({
                success: false,
                message: 'orderValue가 올바르지 않습니다.'
            });
        }

		
        const resumes = await prisma.resumes.findMany({
            orderBy: {
                [orderKey]: orderValue,
            },
            select: {
                resumeId: true,
                title: true,
                content: true,
                auth: true,
                status: true,
                createdAt: true,
                updatedAt: true,
                userId: true
            },
        });
        console.log(orderKey, orderValue);

        return res.status(200).json({ data: resumes });
    } catch (error) {
        console.error('이력서를 가져오는 중 오류 발생:', error);
        return res.status(500).json({ message: '내부 서버 오류' });
    }
});

따라서, orederValue와 orderKey를 받아오는 위치를 req.body로 바꾸었고

validation 부분과 orederBy 부분을 해설 영상을 참고하여 수정하였습니다.

JS가 객체의 키 순서를 보장하지 않고, prisma가 객체 배열을 요하기 때문에 orderBy를 []로 감싸야 합니다.

배열에 래핑되지 않을 경우, 정렬 기준이 변할때 예기치 않은 문제가 생길 수 있습니다.

 

validation부분의 변화는 우선 쿼리를 실행하기 전에  orderKey와 Value를 검사한 뒤, 두 매개변수 존재 여부와 유효성을 검사하는 방식으로 진행됩니다.

이는 유효성 검사와 경로 처리를 분리하여 안정성을 향상시킨 리팩토링 입니다.

이는 유효성 검사 논리가 확장될 경우 코드가 길어지고 복잡해질 수 있습니다만, 지금 프로젝트는 소규모 프로젝트이기 때문에 문제가 되지 않는다 판단하였습니다. 유효성 검사를 미들웨어로 빼버리는 방식도 생각해볼 수 있을것 같습니다.

 

3. 결과 

 

orderValue로 정렬
status로 정렬

 

4. 배운점 

 

정렬 기능의 수정 과정에서, prisma가 요구하는 방식(또는 문법)에 대한 추가적인 공부가 있었습니다.

또, 한번에 여러 로직을 수행함으로서 코드가 더 멋진 방식으로 작동된다는 생각을 가지고 있었습니다만, 이 방법이 안정성에 문제를 일으킬 수 있다는 것을 알 수 있었습니다. 프로젝트 규모, 요구사항에 따라 구현 방법을 달리 하는 개발자가 되어야겠습니다.

첫번째 코드는 이런 저런 값들을 때려넣다 우연히 작동되는 코드를 급하게 제출했던지라 그 코드에 대해서 생각해볼 시간이 없었습니다. 퇴고를 거쳐 성장할 수 있었습니다.