Skip to content

feat(api-gateway): add API gateway and request router contract - #318

Open
BrayanMQ wants to merge 6 commits into
MindFlowInteractive:mainfrom
BrayanMQ:feat/issue-291-api-gateway-router
Open

feat(api-gateway): add API gateway and request router contract#318
BrayanMQ wants to merge 6 commits into
MindFlowInteractive:mainfrom
BrayanMQ:feat/issue-291-api-gateway-router

Conversation

@BrayanMQ

Copy link
Copy Markdown

Description

Adds the central API gateway module described in #291: a Soroban smart-contract library that models request routing, JWT/OAuth-style authentication, rate limiting, request/response logging, CORS handling, health checks, a circuit breaker, and request transformation for the Quest Service ecosystem.

This follows the same pattern established by the backend_core module (#305/#312): pure, testable logic types built on soroban-sdk, since this repo has no standalone HTTP server — the gateway concepts are modeled as contract-compatible types and pipeline logic that a real contract entrypoint would compose.

Time-dependent operations (token expiry, rate-limit windows, circuit breaker timers) take the current ledger timestamp as an explicit now: u64 parameter instead of reading env.ledger() internally, so a caller reads env.ledger().timestamp() once and passes it down. This also keeps the module fully unit-testable without the testutils feature, which is currently broken in this workspace due to an unrelated ed25519-dalek/rand_core version conflict.

Changes

  • New crate contracts/api_gateway (api-gateway) registered as a workspace member:
    • RouteTable / Route: path + method → backend service resolution, with a requires_auth flag
    • AuthToken / AuthMiddleware: bearer-token validation (missing / expired / wrong scope / authorized)
    • RateLimitState: fixed-window rate limiter with automatic window reset
    • RequestLogEntry / LogLevel: structured request logs with status-derived severity
    • CorsPolicy: origin allow-list with wildcard (*) support
    • HealthCheckResult / HealthStatus: per-service health tracking
    • CircuitBreaker / CircuitState: Closed → Open → HalfOpen → Closed state machine
    • TransformRule / RequestContext: path rewriting and header injection
    • process_request: orchestrates all of the above into a single gateway pipeline (CORS → circuit breaker → rate limit → routing → auth)
    • 45 unit tests covering every outcome branch, including edge cases (expired token, invalid scope, CORS-allowed origin, rate-limit window reset, circuit breaker recovery through HalfOpen)
  • Fixed Cargo.toml: a prior merge left the workspace members array with two conflicting closing brackets, leaving contracts/collateral_lending outside the array and breaking cargo metadata/cargo build for the entire workspace. Repaired as part of registering the new crate.

Closes

Closes #291

Evidence/Media (screenshots/videos)

This is a backend Rust/Soroban library with no UI, so evidence is test/lint/build output rather than screenshots.

Test run (cargo test -p api-gateway --lib):

running 45 tests
test tests::test_auth_middleware_authorized ... ok
test tests::test_auth_middleware_expired ... ok
test tests::test_auth_middleware_invalid_scope ... ok
test tests::test_auth_middleware_missing_token ... ok
test tests::test_auth_token_expired ... ok
test tests::test_auth_token_not_expired ... ok
test tests::test_auth_token_scope ... ok
test tests::test_circuit_breaker_half_opens_after_timeout ... ok
test tests::test_circuit_breaker_opens_after_threshold ... ok
test tests::test_circuit_breaker_starts_closed ... ok
test tests::test_circuit_breaker_success_resets ... ok
test tests::test_cors_allows_registered_origin ... ok
test tests::test_cors_rejects_unlisted_origin ... ok
test tests::test_cors_wildcard_allows_any ... ok
test tests::test_health_check_degraded_is_operational ... ok
test tests::test_health_check_healthy_is_operational ... ok
test tests::test_health_check_unhealthy_not_operational ... ok
test tests::test_log_entry_level_error ... ok
test tests::test_log_entry_level_info ... ok
test tests::test_log_entry_level_warn ... ok
test tests::test_process_request_authorized_with_token ... ok
test tests::test_process_request_circuit_open ... ok
test tests::test_process_request_circuit_recovers_through_half_open ... ok
test tests::test_process_request_cors_allowed_origin_routes ... ok
test tests::test_process_request_cors_rejected ... ok
test tests::test_process_request_expired_token_unauthorized ... ok
test tests::test_process_request_invalid_scope_unauthorized ... ok
test tests::test_process_request_not_found ... ok
test tests::test_process_request_rate_limit_resets_after_window ... ok
test tests::test_process_request_rate_limited ... ok
test tests::test_process_request_routed_public ... ok
test tests::test_process_request_unauthorized_without_token ... ok
test tests::test_rate_limit_allows_under_limit ... ok
test tests::test_rate_limit_rejects_over_limit ... ok
test tests::test_rate_limit_resets_after_window ... ok
test tests::test_request_context_headers ... ok
test tests::test_request_context_rewrite ... ok
test tests::test_request_context_rewrite_no_match_leaves_path ... ok
test tests::test_route_matches ... ok
test tests::test_route_table_is_empty ... ok
test tests::test_route_table_len ... ok
test tests::test_route_table_resolve_found ... ok
test tests::test_route_table_resolve_not_found ... ok
test tests::test_transform_rule_applies_on_match ... ok
test tests::test_transform_rule_no_match ... ok

test result: ok. 45 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

Lint (cargo clippy -p api-gateway --lib --tests): clean, no warnings.

Build (cargo build -p api-gateway --release): succeeds.

Workspace sanity (cargo metadata --no-deps): now resolves cleanly for the entire workspace (previously broken by the pre-existing Cargo.toml bug fixed in this PR).

Notes

  • No automated line-coverage tool (cargo-tarpaulin/cargo-llvm-cov) is available in this environment (tarpaulin has limited Windows support), so the "100% coverage" acceptance criterion was verified manually by mapping every public function and branch to at least one test, rather than via a generated coverage report. Happy to re-run with tarpaulin in CI if that's preferred.
  • JWT/OAuth support is modeled as bearer-token validation (subject, expiry, scope) rather than real signature verification, since this is a #![no_std] Soroban contract library with no HTTP layer — there's no literal "JWT" to decode. This mirrors how the existing backend_core module (response formatting/compression) models HTTP-adjacent concepts within the constraints of a smart-contract environment.
  • The Cargo.toml fix is a pre-existing bug unrelated to API Gateway and Request Router #291, but it blocked cargo build/cargo test for the whole workspace, so it had to be fixed to register and test the new crate.

BrayanMQ added 5 commits July 28, 2026 10:12
A prior merge left two conflicting closing brackets in the members
array, leaving contracts/collateral_lending outside the array and
breaking cargo metadata/build for the whole workspace.
New workspace member for the central API gateway module (issue MindFlowInteractive#291).
…th checks, circuit breaker, and request transformation

Provides the core logic for the central API gateway: a route table
resolving path+method to backend services, JWT/OAuth-style token
authentication, a fixed-window rate limiter, structured request
logging, a CORS origin allow-list, service health tracking, a
Closed/Open/HalfOpen circuit breaker, and path-rewrite/header
transformation for outgoing requests. process_request() orchestrates
all of these into a single gateway pipeline.

Closes MindFlowInteractive#291
Adds integration-level tests through process_request for expired
tokens, invalid scope, CORS-allowed origins, rate-limit window reset,
and circuit breaker recovery through the HalfOpen state, plus unit
tests for the previously untested RouteTable::is_empty and the
no-match branch of RequestContext::apply_rewrite. Also resolves two
clippy lints (manual_find, len_without_is_empty).
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@BrayanMQ Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API Gateway and Request Router

2 participants