[Camel in Action] 10-1. Camel REST DSL로 RESTful API 서버 구축하기

Camel REST DSL이란?

Camel은 REST 서버를 구축하기 위한 REST DSL을 제공합니다. Undertow, Jetty, Servlet 등 여러 HTTP 서버 중 원하는 것을 선택하고, 동일한 DSL 문법으로 REST API를 정의할 수 있습니다. Spring MVC나 JAX-RS 대신 Camel을 선택하면 REST 엔드포인트에서 복잡한 통합 로직을 자연스럽게 표현할 수 있습니다.

REST DSL 기본 구조

public class OrderRestRoutes extends RouteBuilder {
  @Override
  public void configure() throws Exception {
    // REST 설정
    restConfiguration()
      .component("undertow")
      .host("0.0.0.0")
      .port(8080)
      .bindingMode(RestBindingMode.json); // 자동 JSON 직렬화

    // REST 엔드포인트 정의
    rest("/orders")
      .get("/").to("direct:listOrders")
      .get("/{id}").to("direct:getOrder")
      .post("/").type(OrderDto.class).to("direct:createOrder")
      .put("/{id}").type(OrderDto.class).to("direct:updateOrder")
      .delete("/{id}").to("direct:deleteOrder");

    // 실제 처리 라우트
    from("direct:listOrders")
      .to("bean:orderService?method=findAll");

    from("direct:getOrder")
      .to("bean:orderService?method=findById(${header.id})");

    from("direct:createOrder")
      .to("bean:orderService?method=create");
  }
}

Path Parameter와 Query Parameter 처리

REST 경로의 변수는 헤더로, 쿼리 파라미터는 헤더나 직접 접근으로 처리합니다.

rest("/products")
  .get("/{category}?page={page}&size={size}")
  .to("direct:searchProducts");

from("direct:searchProducts")
  .process(exchange -> {
    String category = exchange.getIn().getHeader("category", String.class);
    int page = exchange.getIn().getHeader("page", 0, Integer.class);
    int size = exchange.getIn().getHeader("size", 10, Integer.class);
    // 서비스 호출
  });

JSON 자동 바인딩

bindingMode(RestBindingMode.json)를 설정하면 Camel이 자동으로 JSON ↔ Java 객체 변환을 처리합니다. Jackson이 기본 변환기로 사용됩니다.

rest("/orders")
  .post("/")
    .type(OrderDto.class)      // 요청 역직렬화 타입
    .outType(OrderResponse.class) // 응답 직렬화 타입
  .to("direct:createOrder");

from("direct:createOrder")
  .process(exchange -> {
    OrderDto dto = exchange.getIn().getBody(OrderDto.class); // 자동 변환됨
    OrderResponse response = orderService.create(dto);
    exchange.getIn().setBody(response); // 자동으로 JSON 응답
  });

Swagger/OpenAPI 문서 자동 생성

camel-swagger-java 의존성을 추가하면 REST DSL 정의를 기반으로 Swagger UI와 OpenAPI 스펙을 자동 생성합니다.

restConfiguration()
  .component("undertow")
  .port(8080)
  .enableCORS(true)
  .dataFormatProperty("prettyPrint", "true")
  .contextPath("/api")
  .apiContextPath("/api-doc")    // Swagger JSON 경로
  .apiProperty("api.title", "Order API")
  .apiProperty("api.version", "1.0.0");

http://localhost:8080/api-doc에서 OpenAPI JSON을, Swagger UI 경로에서 인터랙티브 문서를 확인할 수 있습니다.

에러 응답 처리

onException(NotFoundException.class)
  .handled(true)
  .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(404))
  .setBody(simple("{"error": "리소스를 찾을 수 없습니다"}"));

onException(ValidationException.class)
  .handled(true)
  .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400))
  .setBody(simple("{"error": "${exception.message}"}"));

Leave a Comment