Implementing Internal‑Only APIs in Spring Cloud: Microservice Isolation, Gateway Whitelist, and AOP Approaches
This article explains three practical solutions for exposing internal‑only APIs in a Spring Cloud environment—separating services, using a gateway with a Redis whitelist, and applying a gateway‑plus‑AOP strategy—complete with code examples and deployment tips.
Hello everyone, I'm Chen. When developing business services we often need an interface that should not be exposed externally and can only be called between internal services. This article explores feasible solutions and demonstrates one of them in detail.
1. Microservice Isolation for Internal and External APIs
Place externally exposed interfaces and internally‑only interfaces in two separate microservices: one service exposes all its APIs to the outside, while the other aggregates only the internal APIs for intra‑network calls.
This approach requires an additional microservice that aggregates internal‑only business interfaces, increasing system complexity, request latency, and maintenance cost.
2. Gateway + Redis Whitelist Mechanism
Maintain a whitelist of allowed interfaces in Redis; when a request reaches the gateway, the gateway checks Redis and forwards the request only if the interface is on the whitelist.
The advantage is zero intrusion to business code—just maintain the whitelist. The drawback is the continuous effort required to manage the whitelist, which often involves ticket submissions, and the added latency of per‑request checks, making the cost‑benefit ratio low.
3. Gateway + AOP Approach
Instead of checking a whitelist at the gateway, this method determines the request source and delegates the decision to the business side, reducing gateway load and improving response speed.
External requests always pass through the gateway, while internal service‑to‑service calls use Kubernetes services directly. By adding a custom header (e.g., from=public) at the gateway, business services can inspect the header: if present, the request is external; if absent, it is internal.
The AOP solution distributes access‑control logic across business services, eliminating a gateway bottleneck and improving code readability, though it introduces some code intrusion that can be mitigated with annotations.
Practical Implementation
Below is a concrete code demonstration of the AOP approach.
First, add the external‑network identifier header on the gateway side:
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(
exchange.mutate().request(
exchange.getRequest().mutate()
.header("id", "")
.header("from", "public")
.build())
.build());
}
@Override
public int getOrder() {
return 0;
}
}Next, create the AOP aspect and annotation for internal‑only access control:
@Aspect
@Component
@Slf4j
public class OnlyIntranetAccessAspect {
@Pointcut("@within(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)")
public void onlyIntranetAccessOnClass() {}
@Pointcut("@annotation(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)")
public void onlyIntranetAccessOnMethod() {}
@Before(value = "onlyIntranetAccessOnMethod() || onlyIntranetAccessOnClass()")
public void before() {
HttpServletRequest hsr = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String from = hsr.getHeader("from");
if (!StringUtils.isEmpty(from) && "public".equals(from)) {
log.error("This api is only allowed invoked by intranet source");
throw new MMException(ReturnEnum.C_NETWORK_INTERNET_ACCESS_NOT_ALLOWED_ERROR);
}
}
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OnlyIntranetAccess {}Finally, annotate any API that should be internal‑only:
@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
return "该接口只允许内部服务调用";
}Final Note (Please Support)
All of my articles are carefully prepared. I have compiled three columns into PDFs, which can be obtained by following the public account "Code Monkey Technical Column" and replying with the corresponding keywords (e.g., "Spring Cloud Advanced"). If this article helped you, please like, view, share, and bookmark—it fuels my continued writing.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
