API Gateway 실습
APIGateway
클라이언트 사이드 로드 밸런싱 실습에 사용한 Order, Product 이용
Order와 Product를 유레카 서버에 등록 필요
FeignClient
사용하지 않을 예정으로@EnableFeignClients
어노테이션은 없어도 되지만 현재는 이전 코드에서 실습하는 거라 지우지는 않음
각 컨트롤러의 로직은 단순히 문자열을 반환하고 Product는 로드밸런싱 여부를 확인하기 위해 포트 번호를 포함한다
OrderController
@GetMapping("/order")
public String getOrder() {
return "order detail";
}
ProductController
@GetMapping("/product")
public String getProduct() {
return "product info from port : " + serverPort;
}
gateway 프로젝트 새로 만들어서 Eureka 서버를 지정해준다 (yml 파일)
CustomPreFilter
@Slf4j
@Component //GlobalFilter를 찾아 Gateway의 필터 체인에 추가
public class CustomPreFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
log.info("PreFilter : Request URI {}", request.getURI());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; //최우선
}
}
요청이 게이트웨이로 들어오면 바로 Pre 필터를 타고 해당 요청에 대한 처리 (헤더, 파라미터 수정 또는 인증/인가 처리, 요청에 기반하여 라우팅 경로 변경 등의 작업, 로그 출력 등)를 하고 다음 필터로 넘긴다 (다음 필터가 없으면 백엔드 서비스로 전달)
CustomPostFilter
@Slf4j
@Component
public class CustomPostFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
log.info("Post Filter : Response status code {}", response.getStatusCode());
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE; // 제일 나중
}
}
백엔드 서비스에서 응답이 게이트웨이로 돌아올 때 Post 필터를 타고 마찬가지로 해당 응답에 대한 처리를 필요한 경우 처리를 하고 (현재는 없음) 모든 처리가 끝난 후에 chain.filter(exchange) 로 다음 필터로 넘기는데 다음 필터가 없으면 클라이언트에 응답을 반환한다 응답을 반환한 후에는 응답에 대한 로그를 찍는다
GlobalFilter
인터페이스를 구현하여 Gateway의 전역 필터로 작동한다
Ordered
인터페이스 구현하여 필터의 실행 순서를 정의한다
정리
Pre 필터: 요청을 받자마자 실행되어 요청 관련 작업 수행.
Post 필터: 응답이 돌아올 때 실행되어 응답 관련 작업 수행.
chain.filter(exchange)
를 사용해 요청을 다음 필터 또는 서비스로 넘기고, 응답 처리가 끝나면 Post 필터 작업까지 완료 후 클라이언트에 반환.