Implementing Internal‑Only APIs with Microservice Isolation, Redis Whitelist, and Gateway + AOP

This article explores three practical solutions for exposing APIs only to internal services—microservice isolation, a Redis‑based whitelist via the gateway, and a gateway‑plus‑AOP approach—detailing their trade‑offs and providing complete Java code examples for the chosen method.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Implementing Internal‑Only APIs with Microservice Isolation, Redis Whitelist, and Gateway + AOP

Introduction

When developing business services, you may encounter the requirement that certain interfaces must not be exposed externally and should only be callable between internal services. This article examines three feasible solutions and selects one for implementation.

Feasible Solutions

Three approaches are considered:

Microservice isolation of internal and external interfaces

Redis‑based whitelist mechanism combined with a gateway

Gateway plus AOP to determine access rights on the business side

1. Microservice Isolation

Separate external‑exposed APIs and internal‑only APIs into two distinct microservices. The internal service aggregates all APIs that should only be called within the intranet.

This adds a new microservice for request forwarding, increasing system complexity, latency, and maintenance cost.

2. Gateway + Redis Whitelist

Maintain a whitelist of allowed interfaces in Redis. When a request reaches the gateway, the whitelist is consulted; requests on the list are allowed, others are rejected.

Advantages: zero intrusion into business code; only the whitelist needs maintenance.

Drawbacks: whitelist upkeep requires continuous effort, often needing tickets from developers; each request incurs a whitelist check, adding latency, and the cost‑benefit ratio is low because most traffic is legitimate.

3. Gateway + AOP

Instead of checking the whitelist at the gateway, this approach pushes the source‑checking logic to the business side via AOP, reducing gateway load and improving response speed.

All external requests pass through the gateway; internal service‑to‑service calls bypass it (e.g., via k8s Service).

The gateway adds a custom header (e.g., from=public) to external requests. Business services inspect this header; if present, the request is external and may be blocked for internal‑only APIs.

This distributes access‑control logic across services, eliminates a gateway bottleneck, and improves code readability, though it introduces some code intrusion that can be mitigated with annotations.

Practical Implementation (Solution 3)

First, add an identifier to the request header on the gateway side: from=public Java example of a gateway filter that injects the header:

@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 an AOP aspect and annotation to enforce internal‑only access:

@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 internal‑only endpoint with @OnlyIntranetAccess:

@GetMapping("/role/add")
@OnlyIntranetAccess
public String onlyIntranetAccess() {
    return "该接口只允许内部服务调用";
}

That concludes the implementation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backendaopaccess controlgateway
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.