Distributed, Asynchronous, Scalable, and Lightweight API Gateway
Bus Vortex is a distributed, fully asynchronous, high-performance, scalable, and lightweight API gateway built on Spring WebFlux. Inspired by Taobao's Open Platform, it stands on the shoulders of the Spring ecosystem to provide enterprise-grade API routing and management capabilities.
- Zero Configuration: Start using immediately after adding annotations to your business code
- Automatic Parameter Validation: Built-in support for JSR-303 internationalized parameter validation
- Modular Design: Independent implementation of validation and result return functionality for easy customization
- Annotation-Driven: Simple API definitions using annotations for easy maintenance
- i18n Support: Built-in internationalization for error messages
- Digital Signature: Parameter verification using digital signatures
- Secure Access: Platform access via appKey and secret mechanism
- Signature Verification: MD5, AES, RSA encryption algorithms for secure data transmission
- Rate Limiting: Leaky bucket and token bucket strategies for traffic control
- Permission Control: RBAC-based permission verification
- Session Management: Support for both standalone and distributed sessions
- Authentication: JWT and accessToken support
- Documentation: Auto-generated API documentation
- Encryption: MD5, AES, RSA
- Networking: Netty (encoding/decoding, long connections, auto-reconnect)
- Rate Limiting: Leaky bucket, token bucket algorithms
- Authorization: RBAC, validation
- Session: Standalone, distributed session management
- Documentation: Annotation-based documentation generation
- Authentication: JWT, accessToken
- SDK: Java, C#, JavaScript
- Formats: XML, JSON
public class Assets {
private String id; // Unique route asset ID
private String namespace_id; // Owning namespace
private Integer type; // Optional asset type filter, uses Type.key()
private String app_id; // Application identifier
private String method; // Logical API method name
private Integer verb; // HTTP verb code: 1=GET ... 9=CONNECT
private Integer policy; // Access policy: 0 anonymous, 1-6 secured
private Integer sign; // Signature verification flag
private String version; // API version (matches request parameter 'v')
private String host; // Target hostname
private Integer port; // Target port
private String path; // Downstream path prefix
private String url; // Target URL / endpoint
private String description; // API description
}| Parameter | Description |
|---|---|
| method | API method name (e.g., xxx.xxx.xxx) |
| v | API version number, used with method (e.g., 1.1, 1.2) |
| namespace | Optional namespace route scope |
| app_id | Optional application-specific route scope |
| type | Optional registry type scope. Accepts numeric Type.key() and legacy type names |
| format | Return format (supports json, xml) |
| sign | If decrypt is enabled in config and request contains sign field, decrypt request |
- Runtime candidate chain:
namespace:type:app_id:method:version:verbnamespace:type:method:version:verbnamespace:app_id:method:version:verbnamespace:method:version:verbtype:app_id:method:version:verbtype:method:version:verbapp_id:method:version:verbmethod:version:verb
method,version, andverbare required runtime dimensionsnamespace,type, andapp_idare optional route scopes; when absent the corresponding levels are skippedtypealways uses numericType.key()inside route keysverbalways uses the numeric verb code rather thanGET/POSTtextApiAssets.keyremains the lightweight public aliasmethod:version:verbCode- Registration and lookup share the same candidate chain
- Lookup stops at the first level that has candidates; if that level resolves to multiple assets, the gateway returns
null
verbCode mapping:
1 -> GET2 -> POST3 -> HEAD4 -> PUT5 -> PATCH6 -> DELETE7 -> OPTIONS8 -> TRACE9 -> CONNECT
You can override the built-in route-key strategy by providing a Spring Keying<Keying.RegistrySpec> bean. The default
implementation is RegistryGenerator, and both bus-cortex and bus-vortex now consume the same
Keying<Keying.RegistrySpec> rules.
bus:
vortex:
port: 8765 # Gateway port
path: /router/rest # Gateway path
condition: false # Disable custom MVC condition bridge by default
limit:
enabled: true # Enable rate limiting
performance:
max-connections: 5000
pending-acquire-timeout-seconds: 45
pending-acquire-max-count: 0 # 0 derives max-connections * 2
sanitize-null-like-parameters: true@EnableVortex
@SpringBootApplication
public class TunnelApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(TunnelApplication.class);
app.run(args);
}
}// No custom registry bean is required for the default setup.
// bus-starter/vortex creates AssetsRegistry automatically.@Bean
public Keying<Keying.RegistrySpec> registryKeying() {
return RegistryGenerator.INSTANCE;
}@Component
public class AuthProviderImpl implements AuthorizeProvider {
// Override token/apiKey/license as needed
}Implement WebFilter to extend gateway functionality, such as rate limiting, logging, blacklisting, circuit breaking
(not yet implemented), etc.
@Component
@Order("123")
public class CustomFilter implements WebFilter {
// TODO: Implement filter logic
}Automatically merges a version-prefixed path to RequestMappingInfo. Recommendation: Configure major versions at class level, minor versions can be configured at method level (will override class-level major version).
Routes to different handler methods based on cv and terminal parameters in request headers (extends
getCustomCondition method in RequestMappingHandlerMapping).
Combines RequestMapping functionality with configurations for both @ApiVersion and @ClientVersion.
- ApiVersion: Replaces version-defined paths that require redefining classes or writing conditional logic in code for API upgrades
- ClientVersion: Elegantly avoids writing extensive version logic when dealing with interfaces already in use by clients
@RequestMapping("/t")
@RestController
@ApiVersion("5")
public class TController {
// Request path: /4/t/get
@RequestMapping(value = "/get")
public String get1() {
return "Old API";
}
// Request path: /5.1/t/get
@RequestMapping(value = "/get", params = "data=tree")
@ApiVersion("5.1")
// Method's @ApiVersion takes precedence over class-level, convenient for minor version upgrades
public String get2() {
return "New data";
}
// All three request paths are /c,
// Routes to different methods based on client type in header
// (can be modified to use URL parameters by changing TerminalVersionExpression)
@GetMapping("/c")
@ClientVersion(expression = {"1>6.0.0"})
public String cvcheck1() {
return "Type 1 client, version 6.0.0+";
}
@GetMapping("/c")
@ClientVersion({@TerminalVersion(terminals = 2, op = VersionOperator.GT, version = "6.0.0")})
public String cvcheck2() {
return "Type 2 client, version > 6.0.0";
}
@GetMapping("/c")
@ClientVersion({@TerminalVersion(terminals = 2, op = VersionOperator.LTE, version = "6.0.0")})
public String cvcheck3() {
return "Type 2 client, version <= 6.0.0";
}
}@RestController
@VersionMapping(value = "/t", apiVersion = "5")
public class TController {
@VersionMapping(value = "a", terminalVersion = @TerminalVersion(terminals = 1, op = VersionOperator.EQ, version = "3.0"))
public String t() {
return "5";
}
}<dependency>
<groupId>org.miaixz</groupId>
<artifactId>bus-starter</artifactId>
<version>x.x.x</version>
</dependency>@EnableVortex
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}bus:
vortex:
port: 8765
path: /router/rest
performance:
max-connections: 5000
pending-acquire-timeout-seconds: 45
pending-acquire-max-count: 0
sanitize-null-like-parameters: trueWhen bus.vortex.performance.sanitize-null-like-parameters=true, the gateway removes Java null, "null", and
"undefined" consistently at request ingestion, context enrichment, and outbound forwarding.
Context#getParameters() preserves the familiar Map usage style, but the returned map is a controlled Parameter
instance, so put / putAll / remove still pass through the shared sanitization rules. Query parameters remain
read-only.
context.getParameters().put("status", status);
context.getParameters().putAll(payload);
context.putQueryParameter("lang", "en");- Microservices Gateway: Unified entry point for microservices architecture
- API Version Management: Smooth API upgrades with version-based routing
- Traffic Control: Rate limiting and traffic shaping for high-concurrency scenarios
- Security Enhancement: Signature verification, encryption, and access control
- Multi-Tenant Routing: Route requests based on tenant-specific parameters
| Property | Type | Default | Description |
|---|---|---|---|
| bus.vortex.port | int | 8765 | Gateway server port |
| bus.vortex.path | String | /router/rest | Gateway routing path |
| bus.vortex.condition | boolean | false | Enable custom Spring MVC condition bridge |
| bus.vortex.limit.enabled | boolean | false | Enable rate limiting |
| bus.vortex.performance.max-connections | int | 5000 | Maximum outbound HTTP connection pool size |
| bus.vortex.performance.pending-acquire-timeout-seconds | int | 45 | Maximum time to wait for a pooled outbound connection |
| bus.vortex.performance.pending-acquire-max-count | int | 0 | Maximum pending outbound connection acquisitions; 0 derives max-connections * 2 |
| bus.vortex.performance.sanitize-null-like-parameters | boolean | true | Remove null / "null" / "undefined" parameters before routing |
| Bus Vortex Version | Spring Boot Version | JDK Version |
|---|---|---|
| 8.x | 3.x+ | 17+ |
| 7.x | 2.x+ | 11+ |
- Asynchronous Non-Blocking: Built on WebFlux for high concurrency
- Low Latency: Minimal routing overhead
- High Throughput: Efficient request handling
- Scalable: Horizontal scaling support
Implement WebFilter for custom request/response processing:
@Component
@Order(1)
public class LoggingFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// Custom logic
return chain.filter(exchange);
}
}Register and update routes dynamically using Registry implementation.
Integrate with service discovery for automatic load balancing.
A: Implement the encryption interface and configure it in the application properties.
A: Enable rate limiting and configure thread pools appropriately.
A: Yes, use @ApiVersion and @ClientVersion for version-specific routing.
Contributions are welcome! Please feel free to submit a Pull Request.