# Apache ShenYu: a Java API gateway built around a plugin chain

> Apache ShenYu proxies HTTP, Dubbo, gRPC, SOFA and Spring Cloud traffic through an ordered chain of hot-swappable plugins, with a separate admin process pushing selector and rule configuration to the data plane. It is a fit for JVM shops that want gateway policy in Java; it is a poor fit for teams that want a single static config file.

**apache/shenyu** — Apache ShenYu is a Java native API Gateway for service proxy, protocol conversion and API governance.

- Repository: https://github.com/apache/shenyu
- Website: https://shenyu.apache.org/
- Stars: 8,840 · Forks: 3,074
- Language: Java
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/apache-shenyu

## The problem ShenYu solves, and who it is actually for

Most gateways assume HTTP. ShenYu's README lists proxy support for Apache Dubbo, Spring Cloud, gRPC, SOFA, TARS, WebSocket and MQTT, which is a different starting assumption. If your internal calls are Dubbo RPC or gRPC rather than REST, a gateway that only forwards HTTP forces you to write and maintain a translation layer. ShenYu treats those protocols as first-class proxy targets.

The second assumption is that gateway behaviour is Java code. The README describes plugins as "the heart of Apache ShenYu" and says they are extensible and hot-pluggable, and the repository has a dedicated shenyu-plugin directory plus a documented custom-plugin path on the project site. That is a real commitment: routing policy lives in the same language and build as your services, and the people who change it are Java developers.

The intended audience is therefore a JVM-centric platform team. If your services are Go or Node and your gateway operators do not read Java, the plugin model is a cost rather than a feature, and the project's own plugin catalogue will not cover your custom logic without someone writing Java anyway.

## Selector, rule and the plugin chain of responsibility

The README states that when a request arrives, ShenYu executes it through all enabled plugins in a chain of responsibility. Each plugin decides whether it applies and what to do. That is the core mechanism: the gateway is not a router with a fixed pipeline, it is a pipeline whose stages are installed and enabled independently.

Configuration is two-layered. A selector is described as the first route, coarser grained, for example at module level. A rule is the second route, finer grained, for example at method level within a module. The README adds a constraint worth remembering: the selector and the rule match only once, and the match is returned, so the coarsest granularity should be sorted last. Ordering is not cosmetic here; it determines which rule wins.

The repository layout shows how the pieces are separated: shenyu-admin and shenyu-bootstrap are distinct top-level modules, with shenyu-sync-data-center, shenyu-register-center and shenyu-admin-listener alongside them. The Admin holds and edits configuration; Bootstrap is the process that serves traffic; a sync channel carries changes between them. The quick start wires exactly that up, passing a WebSocket URL from Bootstrap to Admin.

## Installing Apache ShenYu with Docker and routing your first request

The README's quick start uses Docker and three steps. First create a network so the two containers can resolve each other by name:

```bash
docker network create shenyu
```

Then start the Admin, which listens on port 9095:

```bash
docker pull apache/shenyu-admin
docker run -d --name shenyu-admin-quickstart -p 9095:9095 --net shenyu apache/shenyu-admin
```

Next start Bootstrap, the data plane, on port 9195. The README enables local mode with shenyu.local.enabled=true and points the sync WebSocket at the Admin container:

```bash
docker pull apache/shenyu-bootstrap
docker run -d --name shenyu-quickstart -p 9195:9195 -e "shenyu.local.enabled=true" -e SHENYU_SYNC_WEBSOCKET_URLS=ws://shenyu-admin-quickstart:9095/websocket --net shenyu apache/shenyu-bootstrap
```

With both running, register a route. The README posts to the plugin selectorAndRules endpoint with a localKey header of 123456, which is the default standalone key:

```bash
curl --location --request POST 'http://localhost:9195/shenyu/plugin/selectorAndRules' \
--header 'Content-Type: application/json' \
--header 'localKey: 123456' \
--data-raw '{
    "pluginName": "divide",
    "selectorHandler": "[{\"upstreamUrl\":\"127.0.0.1:8080\"}]",
    "conditionDataList": [{
        "paramType": "uri",
        "operator": "match",
        "paramValue": "/**"
    }],
    "ruleDataList": [{
        "ruleHandler": "{\"loadBalance\":\"random\"}",
        "conditionDataList": [{
            "paramType": "uri",
            "operator": "match",
            "paramValue": "/**"
        }]
    }]
}'
```

If your backend runs on the host rather than in a container, the README notes that upstreamUrl must be set to host.docker.internal:8080, or the container must be started with --network host instead of --net shenyu. Requests then go to http://localhost:9195/helloworld and are proxied to the upstream. The README does not document rollback of a selector and rule change, so plan how you will revert a bad route before you push one.

## The Admin, Bootstrap split is the real operational cost

Running two processes is not incidental. The Admin owns configuration and the Bootstrap owns traffic, so a sync failure is a silent divergence: Bootstrap keeps serving the last configuration it received while the Admin shows something newer. The repository has an entire shenyu-sync-data-center module and a shenyu-admin-listener module, which tells you the project treats sync as a subsystem rather than a detail.

The quick start sidesteps part of this by enabling local mode, shenyu.local.enabled=true, and using the default localKey of 123456. The README also says that if you need a custom localKey you can generate one with a sha512 tool based on plaintext and update the shenyu.local.sha512Key property. That default key is convenient for a laptop and unsuitable for anything reachable from a network; it is a shared secret that authorises configuration writes.

A second limitation is the JDK baseline. The project badge states JDK 17+, and the build is Maven-based, driven through the wrapper script mvnw and the Makefile targets build-admin and build-bootstrap with the release profile. Teams still on Java 8 cannot adopt ShenYu without an upgrade first, and that upgrade is usually larger than the gateway migration itself.

Finally, ShenYu is the wrong tool when your routing needs are genuinely static. If you have twenty services and a routing table that changes twice a year, an Admin UI, a sync channel and a plugin chain add moving parts without adding capability.

## How ShenYu differs from APISIX

The question of ShenYu against APISIX comes up often enough to be a real search query, and the difference is not primarily performance. APISIX is built on NGINX and Lua, and its configuration model is declarative, oriented around a control plane and a set of configuration objects. ShenYu is Java and Reactor-based, and its extension point is a Java plugin loaded into the chain of responsibility described in the README.

That produces a concrete split. With ShenYu, adding a bespoke policy means writing a Java class, packaging it, and loading it into a JVM you already run and monitor. The README states plugins are hot-pluggable and dynamically loaded, which is the payoff for that choice. With APISIX, custom logic is typically Lua or a plugin in a different runtime, which is cheaper for a small tweak and less natural if your platform team lives in Java.

The proxy targets differ too. ShenYu's README lists Dubbo, SOFA and TARS support, which reflects a Chinese microservice ecosystem where those RPC frameworks are common. APISIX is not presented in this material as covering those protocols. If your services speak Dubbo, that single fact may settle the choice regardless of anything else.

## Licence, release cadence and what an upgrade costs

ShenYu is licensed under Apache-2.0 and is an Apache Software Foundation project, with the standard LICENSE and NOTICE files at the repository root, plus SECURITY.md and SECURITY_MODEL.md. For most organisations that means no copyleft obligation on your own services, and no per-node cost. This is a description of the licence, not legal advice; if you redistribute modified ShenYu, read the NOTICE requirements yourself.

The release history shows v2.7.1 on 2026-07-08, v2.7.0.3 on 2025-11-26 and v2.7.0.2 on 2025-08-20. The Makefile still defaults VERSION to 2.7.1-SNAPSHOT, so master is ahead of the last tagged release. The last push to the repository was on 2026-09-21.

Upgrade cost is concentrated in the plugin surface. Because plugins are loaded into a chain and configuration is stored in the Admin, a version change can affect both your custom plugins and the shape of selector and rule data. The repository carries shenyu-e2e and shenyu-integrated-test modules, which suggests the project tests these paths, but the README does not publish a compatibility or deprecation policy for plugin interfaces. Treat a minor version bump as something to stage, not something to apply in place.

## Conclusion

Adopt Apache ShenYu if your services are JVM-based, you want gateway policy expressed as Java plugins, and you are willing to run the Admin process alongside the Bootstrap data plane. Do not adopt it if you want a gateway configured from one versioned file, or if your team has no Java maintenance capacity, because the plugin chain and the Admin-to-Bootstrap sync path are code you will have to read. Before committing, verify three things in a staging environment: that the sync channel you pick (WebSocket, as used in the README quick start, or another of the sync-data-center options) survives an Admin restart, that your JDK is 17 or newer, and that the divide plugin's upstreamUrl reaches your backend from inside the container network.

## FAQ

### What is Apache ShenYu?

It is a Java native API gateway for service proxy, protocol conversion and API governance, licensed under Apache-2.0. The README lists proxy support for Apache Dubbo, Spring Cloud, gRPC, SOFA, TARS, WebSocket and MQTT, with security, API governance and observability handled by plugins.

### How do I install Apache ShenYu with Docker?

The README's quick start creates a Docker network named shenyu, runs apache/shenyu-admin on port 9095, then runs apache/shenyu-bootstrap on port 9195 with shenyu.local.enabled=true and SHENYU_SYNC_WEBSOCKET_URLS pointing at the Admin container's websocket endpoint.

### How does Apache ShenYu compare with APISIX?

ShenYu is Java and Reactor-based and extends through hot-pluggable Java plugins, while APISIX is built on NGINX and Lua with a declarative configuration model. ShenYu's README also lists Dubbo, SOFA and TARS proxy support, which APISIX is not presented as covering in this material.

### What Java version does Apache ShenYu require?

The project badge states JDK 17+. The build runs through the Maven wrapper mvnw and the Makefile targets build-admin and build-bootstrap with the release profile.

### What is the default localKey in Apache ShenYu and how do I change it?

The README's standalone example sends localKey: 123456. To use a different key, the README says to generate one with a sha512 tool from plaintext and update the shenyu.local.sha512Key property.

## Sources

- [apache/shenyu on GitHub](https://github.com/apache/shenyu)
- [License: Apache-2.0](https://github.com/apache/shenyu/blob/master/LICENSE)
- [Project website](https://shenyu.apache.org/)
- [README](https://github.com/apache/shenyu/blob/master/README.md)
- [Releases](https://github.com/apache/shenyu/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apache-shenyu
