pgms

[5주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 23

Ejah 2026. 2. 4. 18:17

백엔드 심화: 인증과 비동기 처리 (Channels API)

이번 글에서는 channels API를 구현하면서
유효성 검사 → 에러 처리 → CRUD → 리팩터링 → 미들웨어 분리까지
백엔드에서 꼭 필요한 심화 개념들을 정리해본다.

 

1. 유효성 검사

API에서 가장 먼저 중요한 것은 요청 값이 정상적인지 검증하는 것이다.
잘못된 요청이 그대로 DB까지 들어가면, 예외 처리도 복잡해지고 데이터 무결성도 깨진다.

 

if (!req.body.name) {
  return res.status(400).json({
    message: "name 값이 필요합니다."
  });
}
  • 필수 값이 누락되었는지
  • 타입이 올바른지
  • 빈 문자열은 아닌지

이런 검증은 DB 접근 전에 반드시 처리하는 것이 좋다.

 

2. userId 처리

이 API는 특정 사용자의 채널 정보를 다루기 때문에 userId가 핵심 식별자 역할을 한다.

const userId = req.user.id;
  • 인증 미들웨어를 통해 req.user에 사용자 정보 저장
  • 클라이언트가 직접 userId를 넘기지 않도록 설계
  • 보안과 데이터 신뢰성 모두 향상

userId는 요청 바디가 아니라 인증 결과에서 가져오는 것이 안전하다.

 

3. name 추가 그리고 return 등장

채널 생성 시 단순히 성공 여부만 반환하는 것이 아니라,
생성된 리소스를 함께 반환하도록 수정했다.

res.status(201).json({
  message: "채널 생성 완료",
  channel: {
    id: result.insertId,
    name: req.body.name
  }
});

이렇게 하면 클라이언트 입장에서:

  • 다시 조회할 필요가 없고
  • UX도 훨씬 좋아진다

 REST API에서는 생성된 자원을 응답으로 돌려주는 패턴이 자주 사용된다.

 

4. SQL 에러 처리 (err)

DB 작업은 언제든 실패할 수 있기 때문에 에러 처리는 필수다.

connection.query(sql, params, (err, result) => {
  if (err) {
    return res.status(500).json({
      message: "DB 에러 발생",
      error: err
    });
  }
});
  • SQL 문법 오류
  • 컬럼 누락
  • DB 연결 문제

이런 에러를 그대로 방치하면 서버가 죽거나 응답이 멈출 수 있다.

 최소한 500 에러로 클라이언트에 명확한 신호를 주자.

 

5. channels 리팩터링 + API 우선순위

기능이 늘어나면서 코드가 점점 길어졌고,
이를 계기로 역할 기준으로 리팩터링을 진행했다.

  • 라우터: 요청/응답 담당
  • 서비스: 비즈니스 로직
  • DB: 쿼리 전담

또한 API 우선순위를 다음 기준으로 정리했다.

  1. 인증 / 권한
  2. 유효성 검사
  3. DB 처리
  4. 응답 반환

 흐름이 보이기 시작하면 디버깅과 유지보수 난이도가 크게 낮아진다.

 

6. update

채널 이름을 수정하는 API에서는
존재 여부 확인 → 수정 → 결과 확인 순서가 중요하다.

if (result.affectedRows === 0) {
  return res.status(404).json({ message: "채널이 존재하지 않습니다." });
}
  • update는 성공처럼 보여도 실제로는 수정된 행이 없을 수 있다
  • affectedRows 체크는 필수

 update API에서 이 검증을 빼먹으면 버그가 숨어들기 쉽다.

 

7. delete

삭제 API도 update와 마찬가지로 결과 검증이 중요하다.

if (result.affectedRows === 0) {
  return res.status(404).json({ message: "삭제할 채널이 없습니다." });
}

 

  • 이미 삭제된 데이터
  • 존재하지 않는 ID

이런 경우를 명확히 구분해서 응답해야 한다.

 delete 역시 성공/실패 기준을 명확히 하자.

 

8. 검사 미들웨어 분리

유효성 검사 코드가 반복되기 시작하면서
이를 미들웨어로 분리했다.

const validateChannelName = (req, res, next) => {
  if (!req.body.name) {
    return res.status(400).json({ message: "name 값이 필요합니다." });
  }
  next();
};
router.post('/channels', validateChannelName, createChannel);
  • 코드 중복 제거
  • 가독성 향상
  • 테스트도 쉬워짐

검사 로직은 미들웨어로 분리하는 게 정석이다.

 

마무리

이번 글에서는 단순 CRUD를 넘어서,

  • 유효성 검사
  • 인증 기반 userId 처리
  • SQL 에러 핸들링
  • API 리팩터링
  • 미들웨어 분리

까지 백엔드에서 꼭 필요한 실전 포인트들을 정리해봤다.

다음에는


JWT 인증 흐름 또는 트랜잭션 처리로 이어가볼 예정이다.