Best Practices
Recommended patterns and practices for the LegionEdge Platform
This guide covers recommended patterns for security, performance, error handling, and reliability when building on the LegionEdge Platform.
Security
Use Environment-Specific API Keys
Never use production keys in development. Create separate keys for each environment:
// Each environment should have its own key
const client = new LegionEdge({
apiKey: process.env.LEGIONEDGE_API_KEY!, // different per environment
environment: process.env.LEGIONEDGE_ENV as "development" | "staging" | "production",
});Minimize API Key Scopes
Grant only the permissions each key needs:
// A key for a read-only dashboard
const dashboardKey = await client.apiKeys.create({
organizationId: orgId,
name: "Dashboard Read-Only",
scopes: ["projects:read", "resources:read", "deployments:read"],
expiresIn: "30d",
});Rotate Keys Regularly
Set up automated key rotation:
const rotated = await client.apiKeys.rotate(keyId, {
gracePeriod: "24h",
});
// Update your secrets manager with rotated.plaintextValidate Webhook Signatures
Always verify webhook payloads before processing them:
import { verifyWebhookSignature } from "@legionedge/sdk";
function handleWebhook(req: Request) {
const isValid = verifyWebhookSignature({
payload: req.body,
signature: req.headers["x-legionedge-signature"] as string,
secret: process.env.WEBHOOK_SECRET!,
});
if (!isValid) {
throw new Error("Invalid webhook signature");
}
}Error Handling
Use Typed Error Handling
The SDK provides typed errors for each error category:
import {
LegionEdge,
LegionEdgeError,
RateLimitError,
AuthenticationError,
NotFoundError,
} from "@legionedge/sdk";
try {
await client.projects.get(projectId);
} catch (err) {
if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter}s`);
} else if (err instanceof AuthenticationError) {
console.error("Authentication failed. Check your API key.");
} else if (err instanceof NotFoundError) {
console.error(`Project ${projectId} does not exist.`);
} else if (err instanceof LegionEdgeError) {
console.error(`[${err.code}] ${err.message}`);
}
}Configure Retries
Enable automatic retries for transient errors:
const client = new LegionEdge({
apiKey: process.env.LEGIONEDGE_API_KEY!,
retries: {
maxRetries: 3,
backoffMultiplier: 2,
retryableStatusCodes: [429, 502, 503, 504],
},
});Rate Limiting
Respect Rate Limits
Monitor rate limit headers and throttle requests accordingly:
const client = new LegionEdge({
apiKey: process.env.LEGIONEDGE_API_KEY!,
rateLimiting: {
enabled: true,
strategy: "adaptive", // automatically slows down near the limit
},
});Batch Operations
Use batch endpoints when operating on multiple resources:
// Instead of individual calls in a loop
const results = await client.projects.batchGet([
"proj_abc",
"proj_def",
"proj_ghi",
]);Caching
Cache Frequently Accessed Data
Use the SDK's built-in cache for read-heavy workloads:
const client = new LegionEdge({
apiKey: process.env.LEGIONEDGE_API_KEY!,
cache: {
enabled: true,
ttl: 60_000, // 60 seconds
maxEntries: 1000,
},
});Performance
Use Pagination Efficiently
Always paginate large result sets and avoid fetching more data than needed:
// Fetch only what you need
const activeProjects = await client.projects.list({
organizationId: orgId,
status: "active",
perPage: 10,
sort: "updated_at",
order: "desc",
});Select Specific Fields
Reduce payload size by requesting only the fields you need:
const projects = await client.projects.list({
organizationId: orgId,
fields: ["id", "name", "status"],
});Next Steps
- Optimize performance with caching and query strategies.
- Review the troubleshooting guide for common issues.