import { HTTP_STATUS } from '../constants/http-status.constant.js';
import { MESSAGES } from '../constants/message.constant.js';
import addressService from '../services/address.service.js';
class AddressController {
#service;
constructor(service) {
this.#service = service;
}
// 주소 생성
createAddress = async (req, res, next) => {
try {
const { address, addressName } = req.body;
// const userId = 1;
const { userId } = req.user;
const _address = await this.#service.createAddress({
userId: +userId,
address,
addressName,
});
return res.status(HTTP_STATUS.CREATED).json({
status: HTTP_STATUS.CREATED,
message: MESSAGES.ADDRESS.CREATE.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.CREATE.NOT_ERROR, error);
res
.status(HTTP_STATUS.BAD_REQUEST)
.json({ message: MESSAGES.ADDRESS.CREATE.NO_BODY_DATA });
}
};
// 주소 조회
getAddress = async (req, res, next) => {
try {
const _address = await this.#service.getAddress();
return res.status(HTTP_STATUS.OK).json({
status: HTTP_STATUS.OK,
message: MESSAGES.ADDRESS.READ_LIST.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.READ_LIST.NOT_ERROR, error);
res
.status(HTTP_STATUS.BAD_REQUEST)
.json({ message: MESSAGES.ADDRESS.READ_LIST.NO_BODY_DATA });
}
};
// 주소 수정
updateAddress = async (req, res, next) => {
try {
const { addressId } = req.params;
const { address, addressName } = req.body;
const _address = await this.#service.updateAddress({
addressId: +addressId,
address: address,
addressName: addressName,
});
return res.status(HTTP_STATUS.OK).json({
status: HTTP_STATUS.OK,
message: MESSAGES.ADDRESS.UPDATE.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.UPDATE.NOT_ERROR, error);
res
.status(HTTP_STATUS.BAD_REQUEST)
.json({ message: MESSAGES.ADDRESS.UPDATE.NO_BODY_DATA });
}
};
// 주소 삭제
deleteAddress = async (req, res, next) => {
try {
const { addressId } = req.params;
const _address = await this.#service.deleteAddress(+addressId);
return res.status(HTTP_STATUS.OK).json({
status: HTTP_STATUS.OK,
message: MESSAGES.ADDRESS.DELETE.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.DELETE.NOT_ERROR, error);
res
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
.json({ message: error.message });
}
};
// 주소 상세 조회
findAddressById = async (req, res, next) => {
try {
const { addressId } = req.params;
const _address = await this.#service.findAddressById(+addressId);
return res.status(HTTP_STATUS.OK).json({
status: HTTP_STATUS.OK,
message: MESSAGES.ADDRESS.READ_LIST.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.READ_LIST.NOT_ERROR, error);
res
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
.json({ message: error.message });
}
};
// 메인 주소 설정
setMainAddress = async (req, res, next) => {
try {
const { addressId } = req.params;
const { userId } = req.user;
const _address = await this.#service.setMainAddress({
addressId: +addressId,
userId: +userId,
});
return res.status(HTTP_STATUS.OK).json({
status: HTTP_STATUS.OK,
message: MESSAGES.ADDRESS.UPDATE.SUCCEED,
data: _address,
});
} catch (error) {
console.error(MESSAGES.ADDRESS.MAINADDRESS.NOT_ERROR, error);
res
.status(HTTP_STATUS.BAD_REQUEST)
.json({ message: MESSAGES.ADDRESS.DELETE.NO_BODY_DATA });
}
};
}
export default new AddressController(addressService);
오늘은 AddressController에 대한 코드를 살펴보며 해당 코드의 구조와 동작 원리에 대해 학습했습니다. 아래는 주요 내용을 정리한 것입니다.
AddressController는 주소와 관련된 CRUD 및 특정 기능(메인 주소 설정)을 담당하는 클래스입니다. RESTful API의 컨트롤러 역할을 하며, 주요 메서드로는 다음과 같은 기능이 구현되어 있습니다.
주소 생성 (createAddress)
주소 조회 (getAddress)
주소 수정 (updateAddress)
주소 삭제 (deleteAddress)
주소 상세 조회 (findAddressById)
메인 주소 설정 (setMainAddress)
의존성 주입
AddressController는 생성자를 통해 의존성을 주입받습니다. 이는 테스트와 유지보수를 쉽게 해주는 좋은 패턴입니다.
상태 코드와 메시지 관리
HTTP_STATUS와 MESSAGES 상수를 활용하여 코드 가독성과 유지보수성을 높였습니다. 에러 처리
try-catch 구문을 통해 예외를 처리하며, 에러 로그를 남기고 적절한 상태 코드와 메시지를 반환합니다. 비공개 멤버(#)
#service) 멤버 변수를 #을 사용하여 비공개로 설정함으로써 캡슐화를 준수했습니다.중복 코드 제거
try-catch와 응답 구조가 유사하므로, 이를 공통화하는 유틸리티 함수를 도입할 수 있습니다. 데이터 유효성 검사
address, addressName, addressId)에 대한 유효성 검사가 컨트롤러 레벨에서 빠져 있습니다. middleware를 활용하여 사전 검증을 도입할 필요가 있습니다.HTTP 상태 코드와 메시지 매핑
INTERNAL_SERVER_ERROR를 반환하기보다는 NOT_FOUND 또는 BAD_REQUEST가 더 적절할 수 있습니다.로깅 개선
console.error 대신 로깅 라이브러리(e.g., Winston, Bunyan)를 사용하여 로그 수준과 출력 포맷을 체계적으로 관리할 수 있습니다.이 코드는 RESTful API 컨트롤러를 설계할 때의 기본적인 모범 사례를 보여줍니다. 앞으로 비슷한 구조의 코드를 작성할 때 유용한 참고 자료가 될 것입니다.