외부 API를 호출하는 헬퍼 메서드에서 HTTP 응답 코드를 하드코딩으로 처리했습니다.
private String callApi(String url) {
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// 문제 1: 200만 성공으로 처리 (201, 202 등은 실패 처리됨)
if (response.statusCode() == 200) {
return response.body();
}
// 문제 2: 404만 데이터 없음으로 처리
else if (response.statusCode() == 404) {
return null;
} else {
logger.error("API 호출 실패 - 상태 코드: {}", response.statusCode());
return null;
}
} catch (Exception e) { // 문제 3: Exception이 너무 광범위함
logger.error("API 호출 중 예외 발생", e);
return null;
}
}
제가 깊게 생각하지 못했던 부분들을 지적받았습니다.
private String callApi(String url, HttpMethod method) {
try {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(url));
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
logger.debug("API 응답 상태: {} ({}) - URL: {}", response.statusCode(), method, url);
// 개선 1: HttpStatus로 200대 응답 모두 처리
HttpStatus httpStatus = HttpStatus.resolve(response.statusCode());
if (httpStatus != null && httpStatus.is2xxSuccessful()) {
return response.body();
}
// 개선 2: 모든 4xx 에러를 클라이언트 에러로 처리
else if (httpStatus.is4xxClientError()) {
return null; // 데이터 없음
} else {
logger.error("API 호출 실패 - 상태 코드: {}, URL: {}", response.statusCode(), url);
return null;
}
// 개선 3: Exception을 구체적으로 분리
} catch (IOException e) {
logger.error("API 호출 중 I/O 예외 발생 - URL: {}", url, e);
return null;
} catch (InterruptedException e) {
logger.error("API 호출 중 인터럽트 발생 - URL: {}", url, e);
Thread.currentThread().interrupt();
return null;
} catch (IllegalArgumentException e) {
logger.error("잘못된 HTTP 메서드 또는 URL - URL: {}, Method: {}", url, method, e);
return null;
} catch (Exception e) {
logger.error("API 호출 중 예상치 못한 예외 발생 - URL: {}, Method: {}", url, method, e);
return null;
}
}
is2xxSuccessful() 메서드 활용
if (httpStatus.is2xxSuccessful()) {
return response.body();
}
200번대 응답 모두 성공으로 처리 가능!
is4xxClientError() 메서드로 클라이언트 에러 통합 처리
else if (httpStatus.is4xxClientError()) {
return null; // 데이터 없음
}
400번대 모든 클라이언트 에러 처리 가능!
Exception 구체화로 정확한 에러 처리
catch (IOException e) {
logger.error("API 호출 중 I/O 예외 발생 - URL: {}", url, e);
return null;
} catch (InterruptedException e) {
logger.error("API 호출 중 인터럽트 발생 - URL: {}", url, e);
Thread.currentThread().interrupt();
return null;
} catch (IllegalArgumentException e) {
logger.error("잘못된 HTTP 메서드 또는 URL - URL: {}, Method: {}", url, method, e);
return null;
} catch (Exception e) {
logger.error("API 호출 중 예외 발생 - URL: {} Method: {}", url, method, e);
return null;
}
IOException - 입출력 예외
InterruptedException - 인터럽트 예외
IllegalArgumentException - 잘못된 인자 예외
HTTP 상태 코드를 하드코딩(== 200, == 404)하는 대신 Spring의 HttpStatus 클래스를 활용하면
단순해 보이는 상태 코드 처리도 프레임워크가 제공하는 유틸리티를 활용하면 더 견고한 코드를 작성할 수 있습니다!