SDK Overview
Every SDK provides the same functionality:
- Decision:
check,acquire,release - Policy CRUD:
list,get,create,update,delete - Lifecycle:
validate,rollout,rollback - History:
audit,versions - Analytics:
summary
| SDK | Language | HTTP Library | Location |
|---|---|---|---|
| Go | Go 1.25+ | Native engine (embedded) | pkg/rlaas/ |
| Python | Python 3.8+ | requests | sdk/python/ |
| TypeScript | TypeScript / Node.js | fetch | sdk/typescript/ |
| Node.js | Node.js 16+ (plain JS) | http / https (stdlib) | sdk/nodejs/ |
| Java | Java 11+ | java.net.http.HttpClient | sdk/java/ |
| .NET | .NET 8 | HttpClient | sdk/dotnet/ |
| C++ | C++17 / CMake | libcurl + nlohmann/json | sdk/cpp/ |
| Rust | Rust 2021 edition | reqwest + tokio | sdk/rust/ |
| Ruby | Ruby 3.0+ / Rails 7+ | net/http (stdlib) | sdk/ruby/ |
Go SDK (Embedded)
The Go SDK is the native library — import it and evaluate decisions locally with zero network overhead.
import "github.com/rlaas-io/rlaas/pkg/rlaas"
client := rlaas.NewClient()
decision, err := client.Check(ctx, model.RequestContext{
OrgID: "acme",
TenantID: "retail",
SignalType: "http",
Operation: "charge",
Endpoint: "/v1/charge",
Method: "POST",
UserID: "u1",
})
if decision.Allowed {
// proceed
} else {
// return 429 with decision.RetryAfter
}
For concurrency limiting:
decision, release, err := client.StartConcurrencyLease(ctx, req)
if decision.Allowed {
defer release()
// do heavy work
}
Python SDK
Install: pip install rlaas-sdk (or install from sdk/python/)
from rlaas_sdk import RlaasClient, CheckRequest
client = RlaasClient("http://localhost:8080")
# Check decision
decision = client.check(CheckRequest(
request_id="r1",
org_id="acme",
tenant_id="retail",
signal_type="http",
operation="charge",
endpoint="/v1/charge",
method="POST",
user_id="u1"
))
print(f"Allowed: {decision.allowed}, Remaining: {decision.remaining}")
# Create policy
client.create_policy({
"policy_id": "test-limit",
"name": "Test Limit",
"enabled": True,
"scope": {"org_id": "acme", "signal_type": "http"},
"algorithm": {"type": "fixed_window", "limit": 100, "window": "1m"},
"action": "deny",
"rollout_percent": 100
})
# Get audit trail
audit = client.get_audit("test-limit")
# Analytics
summary = client.get_analytics_summary(top=5)
TypeScript SDK
Install: npm install @rlaas/sdk (or import from sdk/typescript/)
import { RlaasClient } from '@rlaas/sdk';
const client = new RlaasClient('http://localhost:8080');
// Check decision
const decision = await client.check({
request_id: 'r1',
org_id: 'acme',
tenant_id: 'retail',
signal_type: 'http',
operation: 'charge',
endpoint: '/v1/charge',
method: 'POST',
user_id: 'u1',
});
console.log(`Allowed: ${decision.allowed}, Remaining: ${decision.remaining}`);
// List policies
const policies = await client.listPolicies();
// Rollout update
await client.rollout('payments-limit', 50);
// Rollback
await client.rollback('payments-limit', 1);
Node.js SDK
Zero-dependency pure JavaScript client — no build step, no TypeScript compiler. Works with require() and import. Node 16+.
Install: npm install @rlaas/node-sdk (or reference sdk/nodejs/)
const { RlaasClient } = require('@rlaas/node-sdk');
const client = new RlaasClient('http://localhost:8080');
const decision = await client.check({
request_id: 'r1',
org_id: 'acme',
tenant_id: 'retail',
signal_type: 'http',
endpoint: '/v1/charge',
method: 'POST',
user_id: 'u1',
});
if (decision.allowed) {
console.log(`allowed — ${decision.remaining} remaining`);
} else {
res.status(429).json({ error: 'rate_limited', retry_after: decision.retry_after });
}
Express middleware:
const { rlaasExpress } = require('@rlaas/node-sdk/middleware');
app.use(rlaasExpress(client, (req) => ({
org_id: req.headers['x-org-id'] ?? 'default',
signal_type: 'http',
endpoint: req.path,
method: req.method,
user_id: req.user?.id,
})));
// Returns 429 automatically when rate limited; passes through on allow.
Fastify hook:
const { rlaasPreHandler } = require('@rlaas/node-sdk/middleware');
fastify.addHook('preHandler', rlaasPreHandler(client, (req) => ({
org_id: req.headers['x-org-id'],
signal_type: 'http',
endpoint: req.url,
method: req.method,
})));
Java SDK
Add dependency from sdk/java/ (Maven, Java 11+).
import io.rlaas.sdk.RlaasClient;
import io.rlaas.sdk.model.CheckRequest;
import io.rlaas.sdk.model.Decision;
RlaasClient client = new RlaasClient("http://localhost:8080");
// Check decision
CheckRequest req = new CheckRequest();
req.setRequestId("r1");
req.setOrgId("acme");
req.setSignalType("http");
req.setOperation("charge");
req.setUserId("u1");
Decision decision = client.check(req);
System.out.println("Allowed: " + decision.isAllowed());
System.out.println("Remaining: " + decision.getRemaining());
// Create policy
String policyJson = """
{
"policy_id": "java-limit",
"name": "Java Test",
"enabled": true,
"scope": {"org_id": "acme", "signal_type": "http"},
"algorithm": {"type": "token_bucket", "limit": 200, "window": "1m", "burst": 50},
"action": "deny",
"rollout_percent": 100
}
""";
client.createPolicy(policyJson);
.NET SDK
Add project reference from sdk/dotnet/ (.NET 8).
using Rlaas.Sdk;
var client = new RlaasClient("http://localhost:8080");
// Check decision
var decision = await client.CheckAsync(new CheckRequest
{
RequestId = "r1",
OrgId = "acme",
TenantId = "retail",
SignalType = "http",
Operation = "charge",
Endpoint = "/v1/charge",
Method = "POST",
UserId = "u1"
});
Console.WriteLine($"Allowed: {decision.Allowed}, Remaining: {decision.Remaining}");
// Policy management
var policies = await client.ListPoliciesAsync();
await client.RolloutAsync("payments-limit", 50);
await client.RollbackAsync("payments-limit", 1);
// Analytics
var summary = await client.GetAnalyticsSummaryAsync(top: 5);
C++ SDK
Add via CMake using FetchContent or copy sdk/cpp/ into your project. Requires libcurl and nlohmann/json.
# CMakeLists.txt
include(FetchContent)
FetchContent_Declare(rlaas_sdk GIT_REPOSITORY https://github.com/rlaas-io/rlaas
GIT_TAG main SOURCE_SUBDIR sdk/cpp)
FetchContent_MakeAvailable(rlaas_sdk)
target_link_libraries(my_app PRIVATE rlaas::sdk)
#include "rlaas/client.h"
int main() {
rlaas::Client client("http://localhost:8080");
// Check decision
rlaas::CheckRequest req;
req.request_id = "r1";
req.org_id = "acme";
req.tenant_id = "retail";
req.signal_type = "http";
req.operation = "charge";
req.endpoint = "/v1/charge";
req.method = "POST";
req.user_id = "u1";
auto decision = client.check(req);
if (decision.allowed) {
// proceed
} else {
// return 429 — decision.retry_after_ms gives the backoff hint
}
// Create policy
std::string policy_json = R"({
"policy_id": "cpp-limit",
"name": "C++ Service Limit",
"enabled": true,
"scope": {"org_id": "acme", "signal_type": "http"},
"algorithm": {"type": "token_bucket", "limit": 500, "window": "1m", "burst": 100},
"action": "deny",
"rollout_percent": 100
})";
client.create_policy(policy_json);
// List policies
auto policies = client.list_policies();
for (const auto& p : policies) {
std::cout << p.policy_id << " — enabled: " << p.enabled << "\n";
}
}
The C++ SDK is header-friendly and has no mandatory runtime dependencies beyond libcurl. Thread-safe for concurrent check() calls sharing one Client instance.
Rust SDK
Add to Cargo.toml (or reference the workspace crate from sdk/rust/):
[dependencies]
rlaas-sdk = { path = "sdk/rust" }
tokio = { version = "1", features = ["full"] }
serde_json = "1"
use rlaas_sdk::{Client, CheckRequest};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Client::new("http://localhost:8080");
// Check decision
let req = CheckRequest {
request_id: "r1".into(),
org_id: "acme".into(),
tenant_id: "retail".into(),
signal_type: "http".into(),
operation: "charge".into(),
endpoint: "/v1/charge".into(),
method: "POST".into(),
user_id: "u1".into(),
..Default::default()
};
let decision = client.check(&req).await?;
if decision.allowed {
// proceed
} else {
eprintln!("rate limited — retry after {}ms", decision.retry_after_ms);
}
// Policy management
let policies = client.list_policies().await?;
println!("policies: {}", policies.len());
client.rollout("payments-limit", 50).await?;
client.rollback("payments-limit", 1).await?;
// Analytics
let summary = client.analytics_summary(5).await?;
println!("top policy: {}", summary.top[0].policy_id);
Ok(())
}
The Rust SDK uses reqwest with connection pooling and is fully async (tokio). All types implement Serialize / Deserialize so you can forward decisions into your own telemetry pipeline.
Ruby SDK
Install: gem install rlaas-sdk (or add to Gemfile from sdk/ruby/):
# Gemfile
gem 'rlaas-sdk', path: 'sdk/ruby'
require 'rlaas_sdk'
client = Rlaas::Client.new('http://localhost:8080')
# Check decision
decision = client.check(
request_id: 'r1',
org_id: 'acme',
tenant_id: 'retail',
signal_type: 'http',
operation: 'charge',
endpoint: '/v1/charge',
method: 'POST',
user_id: 'u1'
)
puts "Allowed: #{decision.allowed}, Remaining: #{decision.remaining}"
# Create policy
client.create_policy(
policy_id: 'ruby-limit',
name: 'Ruby Service Limit',
enabled: true,
scope: { org_id: 'acme', signal_type: 'http' },
algorithm: { type: 'sliding_window', limit: 200, window: '1m' },
action: 'deny',
rollout_percent: 100
)
# Get audit trail
audit = client.audit('ruby-limit')
# Analytics
summary = client.analytics_summary(top: 5)
Rails middleware integration:
# config/initializers/rlaas.rb
RLAAS = Rlaas::Client.new(ENV.fetch('RLAAS_URL', 'http://localhost:8080'))
# app/controllers/application_controller.rb
before_action :enforce_rate_limit
def enforce_rate_limit
decision = RLAAS.check(
org_id: current_org.id,
signal_type: 'http',
endpoint: request.path,
method: request.method,
user_id: current_user&.id
)
render json: { error: 'rate_limited' }, status: 429 unless decision.allowed
end
Common Patterns
Error Handling
All SDKs raise/throw on HTTP errors. Wrap calls in try/catch for production use:
try:
decision = client.check(req)
except Exception as e:
# fail open: allow on error
print(f"RLAAS error: {e}, failing open")
try {
const d = await client.check(req);
} catch (err) {
console.warn('RLAAS error, failing open:', err);
}
try {
Decision d = client.check(req);
} catch (Exception e) {
System.err.println("RLAAS error, failing open: " + e.getMessage());
}
try {
var d = await client.CheckAsync(req);
} catch (Exception ex) {
Console.Error.WriteLine($"RLAAS error: {ex.Message}");
}
const { RlaasError } = require('@rlaas/node-sdk');
try {
const d = await client.check(req);
} catch (err) {
if (err instanceof RlaasError) {
console.warn(`RLAAS ${err.statusCode}: ${err.message}, failing open`);
}
// fail open — allow the request through
}
try {
auto d = client.check(req);
} catch (const rlaas::RlaasException& e) {
// fail open: log and allow
std::cerr << "RLAAS error, failing open: " << e.what() << "\n";
}
match client.check(&req).await {
Ok(d) => { /* use d.allowed */ }
Err(e) => {
// fail open: log and allow
eprintln!("RLAAS error, failing open: {e}");
}
}
begin
decision = client.check(req)
rescue Rlaas::Error => e
# fail open: allow on error
Rails.logger.warn "RLAAS error, failing open: #{e.message}"
return
end
Custom Base URL
All SDKs accept a base URL in the constructor. Point to your production RLAAS server or local sidecar:
# Production
client = RlaasClient("https://rlaas.internal.company.com")
# Local sidecar
client = RlaasClient("http://localhost:18080")