Camel은 REST 서버뿐 아니라 클라이언트로도 탁월합니다. 외부 API를 호출하고 응답을 처리하는 복잡한 로직을 라우트로 표현하면 유지보수가 훨씬 쉬워집니다.
// GET 요청
from("timer:apiCall?period=60000")
.to("rest:get:https://api.example.com/users?bridgeEndpoint=true")
.unmarshal().json(JsonNode.class)
.process(exchange -> {
JsonNode users = exchange.getIn().getBody(JsonNode.class);
// 응답 처리
});
// POST 요청
from("direct:createUser")
.marshal().json()
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("http4://api.example.com/users?bridgeEndpoint=true")
.unmarshal().json(UserResponse.class); 현대 API는 대부분 OAuth 토큰 인증이 필요합니다. Camel에서 토큰을 자동으로 갱신하는 패턴입니다.
// 토큰 캐싱 빈
@Component
public class TokenCache {
private String token;
private Instant expiry;
public String getValidToken() {
if (token == null || Instant.now().isAfter(expiry)) {
refreshToken();
}
return token;
}
}
// 라우트에서 토큰 주입
from("direct:secureApiCall")
.process(exchange -> {
String token = tokenCache.getValidToken();
exchange.getIn().setHeader("Authorization", "Bearer " + token);
})
.to("http4://secure-api.example.com/data?bridgeEndpoint=true"); API 응답 코드에 따라 다른 처리가 필요할 때는 Choice EIP를 활용합니다.
from("direct:apiCall")
.to("http4://api.example.com/resource?bridgeEndpoint=true&throwExceptionOnFailure=false")
.choice()
.when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(200))
.to("bean:successHandler")
.when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(404))
.log("리소스 없음")
.stop()
.when(header(Exchange.HTTP_RESPONSE_CODE).isEqualTo(429))
.log("요청 한도 초과, 재시도")
.delay(60000)
.to("direct:apiCall") // 재귀 호출로 재시도
.otherwise()
.to("direct:errorHandler")
.end(); 외부 API는 일시적으로 실패할 수 있습니다. Camel의 Retry와 Circuit Breaker로 복원력 있는 클라이언트를 구현합니다.
from("direct:resilientApiCall")
.circuitBreaker()
.resilience4jConfiguration()
.slidingWindowSize(10)
.failureRateThreshold(50)
.waitDurationInOpenState(30)
.end()
.to("http4://flaky-api.example.com/data")
.onFallback()
.setBody(simple("{"source":"cache","data":${bean:cacheService.getLatest}}"))
.end(); 대용량 데이터를 페이지 단위로 가져오는 API를 처리할 때는 동적 라우팅으로 반복 호출을 자동화합니다.
from("direct:fetchAllPages")
.setHeader("page", constant(1))
.loopDoWhile(simple("${header.hasMore} == 'true' || ${header.page} == 1"))
.toD("http4://api.example.com/items?page=${header.page}&bridgeEndpoint=true")
.process(exchange -> {
PagedResponse resp = exchange.getIn().getBody(PagedResponse.class);
exchange.getIn().setHeader("hasMore", resp.hasNextPage());
exchange.getIn().setHeader("page", resp.getPage() + 1);
})
.to("direct:processPage")
.end(); 2025년 Apache Camel의 최신 트렌드를 분석합니다. AI/LLM 통합 컴포넌트, 서버리스 배포, Camel K 진화, WebAssembly…
Camel in Action을 완독한 후 Apache Camel의 전체 그림을 다시 정리합니다. 핵심 철학, 학습 경로,…
Apache Camel 2.x에서 3.x, 4.x로 마이그레이션하는 단계별 가이드입니다. 주요 API 변경사항, 제거된 컴포넌트, 자동화 도구…
Apache Camel 라우트에서 발생하는 문제를 디버깅하고 해결하는 실전 기법을 설명합니다. 로그 분석, breakpoint 디버깅, Tracer,…
Apache Camel을 프로젝트에 도입하기 전 알아야 할 핵심 사항을 정리합니다. 학습 곡선, 도입 비용, 적합한…
엔터프라이즈 통합 패턴(EIP) 20가지를 Apache Camel 코드와 함께 한 번에 정리합니다. 메시징 채널, 메시지 라우팅,…