반응형
zuul서버는 API Gateway이다
API Gateway는 API의 요청자인 Client(웹어플리케이션 또는 모바일앱)와 API의 제공자인 backend service를 연결하는 중계자
API Gateway가 필요한 이유
- 인증/인가: 부적절한 요청을 차단하여 Backend service를 보호
- L/B & Routing: Client의 요청에 따라 적절한 backend service를 로드밸런싱하고 연결(라우팅)
- Logging: 유통되는 트래픽 로깅
- Circuit Break: Backend service 장애 감지 및 대처
모든 frontend의 요청을 라우팅하므로 다음의 usecase에도 활용할 수 있습니다.
- 점진적으로 레거시 시스템을 신규 시스템으로 교체: Strangler pattern 적용
- 트래픽 일부만 새로운 서비스로 라우팅: Canary(카나리) 배포 가능
@EnableZuulProxy
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
package com.hyeon.filter;
import static com.netflix.zuul.context.RequestContext.getCurrentContext;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.hyeon.property.UrlProperty;
import com.hyeon.property.UrlProperty.Endpoint;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
@Component
public class AccessibleApiFilter extends ZuulFilter {
@Autowired
private UrlProperty urlProperty;
private final AntPathMatcher matcher = new AntPathMatcher();
@Override
public Object run() throws ZuulException {
RequestContext ctx = getCurrentContext();
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(HttpStatus.NOT_FOUND.value());
return null;
}
// 필터가 동작하는 조건부, true가 return되는 경우 run이 실행됨.
@Override
public boolean shouldFilter() {
RequestContext ctx = getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String prefix = urlProperty.getPrefix();
String apiDocsUrl = prefix + urlProperty.getApiDocsUrl();
List<Endpoint> endpoints = urlProperty.getEndpoints();
String uri = request.getRequestURI();
String method = request.getMethod();
// api-docs 경로는 filter 대상에서 제외.
if (apiDocsUrl.equals(uri) && method.equals(HttpMethod.GET.name())) {
return false;
}
// application.yml에서 정의된 허용 API 목록 외에는 404를 return
return endpoints
.stream()
.noneMatch(
o ->
matcher.match(prefix + o.getPath(), uri) &&
Arrays.stream(o.getMethods()).anyMatch(method::equals)
);
}
@Override
public int filterOrder() {
return 0;
}
@Override
public String filterType() {
return "pre";
}
}
반응형
'개발 > Spring Boot' 카테고리의 다른 글
[Spring Boot] Linux에 Service 배포 (0) | 2023.10.11 |
---|---|
[Spring Boot] Multi Profiles (0) | 2023.10.11 |
[Spring Boot] ssl 인증서 적용 및 발급(Let's Encrypt ) (0) | 2023.10.11 |
[Spring Boot] war 패키징 방법 (0) | 2023.10.10 |
[Spring Boot] spring-integration-ip 이용한 Tcp 통신 (0) | 2023.10.10 |