코드
config server: https://github.com/khc41/config-server
config client: https://github.com/khc41/config-client
MSA 구조의 프로젝트를 시작하면서 고민이 생겼다.
에러코드가 프로젝트별로 중복되는데 어떻게 공통으로 처리해줄 것인가?
데이터베이스에 에러코드를 저장해서 도메인 프로젝트별로 조회하는 방법은 에러가 발생할 때마다 디비에 접근해야 하므로 성능이 안좋을 것 같다고 생각했다.
이 방법에 캐시를 더해서 사용하는 방법도 있지만, 그렇게 되면 에러코드가 바뀔때마다 바로 대응이 안된다는 단점이 있었고, 캐시를 효율적으로 사용하기 힘들 것 같았다.
그래서 고안했던 방법이 바로 Config서버에 property 형식으로 에러코드를 저장하고,
각 도메인 프로젝트에서 시작할때, 일정 주기별로 이 코드를 가져와서 사용하면 괜찮지 않을까..?
이 어노테이션을 이용해 property의 값을 읽어와 hashmap 형태로 만들면, 소스코드에서 사용할 때에 성능상의 이슈 없이 에러코드를 불러올 수 있을 것이라고 생각했다.
@Getter
@Setter
@ToString
public class ErrorCode {
private Integer code;
private String value;
}
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "error.codemap")
public class ErrorCodeManager {
public Map<String, ErrorCode> common = new HashMap<>();
public Map<String, ErrorCode> shop = new HashMap<>();
}
ErrorCodeManager를 사용해 공통으로 사용하는 에러코드, shop이라는 도메인에서 사용하는 에러코드를 불러올 것이다.
자료형이 Map<String, ErrorCode>인 이유는 Map형태의 자료구조에서 String으로 식별자를 두고 ErrorCode를 가져오는 방식으로 채택했기 때문이다.
error:
codemap:
common:
C401:
code: 401
value: LOGIN ERROR
C500:
code: 500
value: INTERNAL SERVER ERROR
shop:
S400:
code: 400
value: 상품등록 실패
ErrorCodeManager에 각각의 HashMap에 에러코드가 담기게 되고 실제로 테스트 코드로 출력해보면 다음과 같이 저장된 것을 확인할 수 있다.
Map<String, ErrorCode> common = errorCodeManager.common;
for (String key : common.keySet()) {
log.info("key = {}, value = {}", key, common.get(key));
}
Map<String, ErrorCode> shop = errorCodeManager.shop;
for (String key : shop.keySet()) {
log.info("key = {}, value = {}", key, shop.get(key));
}
구현이 완료되고 실제 사용은 어떻게 하냐?
HttpStatus의 resolve를 사용하면 해당 HttpStatus를 가져올 수 있다.
응답할 때 해당 map에서 상황에 맞는 코드 조회 후, ResponseEntity로 응답해주면 된다.
ErrorCode errorCode = errorCodeManager.common.get("C401");
return new ResponseEntity<>(errorCode.getValue(), HttpStatus.resolve(errorCode.getCode()));
null 체크는 해주길 바란다.
이렇게 응답하면, 상황에 맞는 메시지와 에러를 client에 응답해줄 수 있다.
일단, msa환경에서 여러 프로젝트에서 사용하는 error code가 중복될 수도 있고, 한곳에 있으면 관리하기 편하기 때문에 이같은 방법을 고안해봤다.
spring cloud의 config server를 사용하면 에러코드 변경 시에도 편하게 대응할 수 있고, map을 사용해서 error code를 찾을 때의 성능도 괜찮을 것이라 생각했다.
하지만, 이 방법보다 더 좋은 방법들도 많을 것이다.
더 좋은 방법이 있으면 다시 글로 공유할 예정이다..
-끝-