Initial commit
This commit is contained in:
15
.claude-plugin/plugin.json
Normal file
15
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "api-gateway-builder",
|
||||
"description": "Build API gateway with routing, authentication, and rate limiting",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Jeremy Longshore",
|
||||
"email": "[email protected]"
|
||||
},
|
||||
"skills": [
|
||||
"./skills"
|
||||
],
|
||||
"commands": [
|
||||
"./commands"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# api-gateway-builder
|
||||
|
||||
Build API gateway with routing, authentication, and rate limiting
|
||||
601
commands/build-api-gateway.md
Normal file
601
commands/build-api-gateway.md
Normal file
@@ -0,0 +1,601 @@
|
||||
---
|
||||
description: Build production-ready API gateway with intelligent routing, authentication, rate limiting, and microservice orchestration
|
||||
shortcut: gateway
|
||||
category: api
|
||||
difficulty: advanced
|
||||
estimated_time: 3-5 hours
|
||||
version: 2.0.0
|
||||
---
|
||||
|
||||
<!-- DESIGN DECISIONS -->
|
||||
<!-- API gateways provide a single entry point for microservices, handling cross-cutting
|
||||
concerns like authentication, rate limiting, and routing. This command generates
|
||||
production-ready gateways using Kong, Express Gateway, or custom Node.js implementations. -->
|
||||
|
||||
<!-- ALTERNATIVES CONSIDERED -->
|
||||
<!-- Direct service-to-service communication: Rejected due to lack of centralized control
|
||||
Client-side load balancing: Rejected as it pushes complexity to clients
|
||||
Service mesh only: Rejected as gateways better handle external traffic -->
|
||||
|
||||
# Build API Gateway
|
||||
|
||||
Creates enterprise-grade API gateway infrastructure that serves as the single entry point for all microservices. Implements intelligent request routing, authentication, rate limiting, load balancing, and response transformation. Supports Kong, Express Gateway, AWS API Gateway, and custom implementations.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this command when:
|
||||
- Managing multiple microservices behind a unified API
|
||||
- Implementing cross-cutting concerns (auth, logging, rate limiting)
|
||||
- Needing request/response transformation between clients and services
|
||||
- Requiring API composition from multiple backend services
|
||||
- Implementing API versioning and backward compatibility
|
||||
- Building for multi-tenant SaaS applications
|
||||
- Enforcing consistent security policies across services
|
||||
|
||||
Do NOT use this command for:
|
||||
- Simple monolithic applications with single API
|
||||
- Internal service-to-service communication (use service mesh instead)
|
||||
- Applications with only one or two endpoints
|
||||
- Purely static content serving
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before running this command, ensure:
|
||||
- [ ] Microservice architecture is defined
|
||||
- [ ] Service discovery mechanism is available
|
||||
- [ ] Authentication strategy is determined
|
||||
- [ ] Rate limiting requirements are specified
|
||||
- [ ] Monitoring infrastructure is ready
|
||||
|
||||
## Process
|
||||
|
||||
### Step 1: Analyze Architecture Requirements
|
||||
The command examines your system architecture:
|
||||
- Maps all backend services and their endpoints
|
||||
- Identifies authentication and authorization needs
|
||||
- Determines rate limiting and throttling requirements
|
||||
- Analyzes request/response transformation needs
|
||||
- Plans for high availability and failover
|
||||
|
||||
### Step 2: Generate Gateway Configuration
|
||||
Creates comprehensive gateway setup:
|
||||
- Route definitions with path matching
|
||||
- Authentication middleware integration
|
||||
- Rate limiting rules per client/endpoint
|
||||
- Request/response transformation pipelines
|
||||
- Circuit breaker configurations
|
||||
|
||||
### Step 3: Implement Middleware Stack
|
||||
Builds layered middleware architecture:
|
||||
- CORS handling and preflight requests
|
||||
- JWT validation and OAuth2 integration
|
||||
- Request logging and metrics collection
|
||||
- Response caching strategies
|
||||
- Error handling and formatting
|
||||
|
||||
### Step 4: Configure Load Balancing
|
||||
Sets up intelligent traffic distribution:
|
||||
- Round-robin, least connections, or weighted routing
|
||||
- Health checking and automatic failover
|
||||
- Sticky sessions when required
|
||||
- Geographic routing for multi-region
|
||||
- A/B testing and canary deployments
|
||||
|
||||
### Step 5: Deploy Monitoring & Analytics
|
||||
Integrates comprehensive observability:
|
||||
- Request/response logging
|
||||
- Performance metrics and tracing
|
||||
- Error rate monitoring
|
||||
- API usage analytics
|
||||
- Real-time dashboards
|
||||
|
||||
## Output Format
|
||||
|
||||
The command generates complete gateway infrastructure:
|
||||
|
||||
```
|
||||
api-gateway/
|
||||
├── src/
|
||||
│ ├── gateway/
|
||||
│ │ ├── server.js
|
||||
│ │ ├── routes/
|
||||
│ │ │ ├── router.js
|
||||
│ │ │ └── service-registry.js
|
||||
│ │ ├── middleware/
|
||||
│ │ │ ├── authentication.js
|
||||
│ │ │ ├── rate-limiter.js
|
||||
│ │ │ ├── transformer.js
|
||||
│ │ │ └── circuit-breaker.js
|
||||
│ │ └── plugins/
|
||||
│ │ ├── logging.js
|
||||
│ │ └── monitoring.js
|
||||
│ ├── config/
|
||||
│ │ ├── gateway.config.js
|
||||
│ │ ├── services.json
|
||||
│ │ └── rate-limits.json
|
||||
│ └── utils/
|
||||
│ ├── load-balancer.js
|
||||
│ └── service-discovery.js
|
||||
├── kong/
|
||||
│ ├── kong.yml
|
||||
│ └── plugins/
|
||||
├── tests/
|
||||
│ └── gateway.test.js
|
||||
└── docs/
|
||||
└── api-gateway-guide.md
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Express Gateway with JWT Authentication
|
||||
|
||||
**Scenario:** Microservices gateway with JWT auth and rate limiting
|
||||
|
||||
**Generated Express Gateway Implementation:**
|
||||
```javascript
|
||||
// gateway/server.js
|
||||
import express from 'express';
|
||||
import httpProxy from 'http-proxy-middleware';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import CircuitBreaker from 'opossum';
|
||||
|
||||
class APIGateway {
|
||||
constructor(config) {
|
||||
this.app = express();
|
||||
this.services = config.services;
|
||||
this.setupMiddleware();
|
||||
this.setupRoutes();
|
||||
this.setupErrorHandling();
|
||||
}
|
||||
|
||||
setupMiddleware() {
|
||||
// CORS configuration
|
||||
this.app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', process.env.ALLOWED_ORIGINS);
|
||||
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||
if (req.method === 'OPTIONS') {
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
// Request logging
|
||||
this.app.use((req, res, next) => {
|
||||
const startTime = Date.now();
|
||||
res.on('finish', () => {
|
||||
const duration = Date.now() - startTime;
|
||||
console.log({
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
status: res.statusCode,
|
||||
duration,
|
||||
ip: req.ip,
|
||||
userAgent: req.get('user-agent')
|
||||
});
|
||||
});
|
||||
next();
|
||||
});
|
||||
|
||||
// Global rate limiting
|
||||
const globalLimiter = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
max: 100, // 100 requests per minute
|
||||
message: 'Too many requests, please try again later',
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false
|
||||
});
|
||||
this.app.use(globalLimiter);
|
||||
}
|
||||
|
||||
setupRoutes() {
|
||||
// Service routes with specific configurations
|
||||
Object.entries(this.services).forEach(([name, config]) => {
|
||||
const { path, target, auth, rateLimit: limits, circuitBreaker } = config;
|
||||
|
||||
// Create middleware chain for this service
|
||||
const middlewares = [];
|
||||
|
||||
// Authentication middleware if required
|
||||
if (auth) {
|
||||
middlewares.push(this.createAuthMiddleware(auth));
|
||||
}
|
||||
|
||||
// Service-specific rate limiting
|
||||
if (limits) {
|
||||
middlewares.push(rateLimit({
|
||||
windowMs: limits.windowMs || 60000,
|
||||
max: limits.max || 50,
|
||||
keyGenerator: (req) => {
|
||||
return req.user?.id || req.ip;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Circuit breaker for resilience
|
||||
const breaker = new CircuitBreaker(
|
||||
this.createProxyMiddleware(target),
|
||||
{
|
||||
timeout: circuitBreaker?.timeout || 3000,
|
||||
errorThresholdPercentage: circuitBreaker?.errorThreshold || 50,
|
||||
resetTimeout: circuitBreaker?.resetTimeout || 30000
|
||||
}
|
||||
);
|
||||
|
||||
// Monitoring circuit breaker events
|
||||
breaker.on('open', () => {
|
||||
console.error(`Circuit breaker opened for ${name}`);
|
||||
});
|
||||
|
||||
// Apply middlewares and proxy
|
||||
this.app.use(path, ...middlewares, (req, res, next) => {
|
||||
breaker.fire(req, res, next)
|
||||
.catch(err => {
|
||||
res.status(503).json({
|
||||
error: 'Service temporarily unavailable',
|
||||
service: name
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createAuthMiddleware(authConfig) {
|
||||
return async (req, res, next) => {
|
||||
const token = req.headers.authorization?.split(' ')[1];
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ error: 'No token provided' });
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||
req.user = decoded;
|
||||
|
||||
// Check permissions if specified
|
||||
if (authConfig.requiredScopes) {
|
||||
const hasPermission = authConfig.requiredScopes.some(scope =>
|
||||
decoded.scopes?.includes(scope)
|
||||
);
|
||||
|
||||
if (!hasPermission) {
|
||||
return res.status(403).json({ error: 'Insufficient permissions' });
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
return res.status(401).json({ error: 'Invalid token' });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
createProxyMiddleware(target) {
|
||||
return httpProxy.createProxyMiddleware({
|
||||
target,
|
||||
changeOrigin: true,
|
||||
onProxyReq: (proxyReq, req) => {
|
||||
// Add tracing headers
|
||||
proxyReq.setHeader('X-Request-ID', req.id || uuid.v4());
|
||||
proxyReq.setHeader('X-Forwarded-For', req.ip);
|
||||
|
||||
// Forward user context if authenticated
|
||||
if (req.user) {
|
||||
proxyReq.setHeader('X-User-ID', req.user.id);
|
||||
proxyReq.setHeader('X-User-Roles', JSON.stringify(req.user.roles));
|
||||
}
|
||||
},
|
||||
onProxyRes: (proxyRes, req, res) => {
|
||||
// Add response headers
|
||||
proxyRes.headers['X-Gateway-Version'] = '1.0.0';
|
||||
proxyRes.headers['X-Response-Time'] = Date.now() - req.startTime;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// config/services.json
|
||||
{
|
||||
"userService": {
|
||||
"path": "/api/users",
|
||||
"target": "http://user-service:3001",
|
||||
"auth": {
|
||||
"required": true,
|
||||
"requiredScopes": ["users:read", "users:write"]
|
||||
},
|
||||
"rateLimit": {
|
||||
"windowMs": 60000,
|
||||
"max": 100
|
||||
},
|
||||
"circuitBreaker": {
|
||||
"timeout": 5000,
|
||||
"errorThreshold": 50,
|
||||
"resetTimeout": 30000
|
||||
}
|
||||
},
|
||||
"productService": {
|
||||
"path": "/api/products",
|
||||
"target": "http://product-service:3002",
|
||||
"auth": {
|
||||
"required": false
|
||||
},
|
||||
"rateLimit": {
|
||||
"windowMs": 60000,
|
||||
"max": 200
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Kong Gateway Configuration
|
||||
|
||||
**Scenario:** Enterprise Kong gateway with plugins
|
||||
|
||||
**Generated Kong Configuration:**
|
||||
```yaml
|
||||
# kong.yml
|
||||
_format_version: "2.1"
|
||||
|
||||
services:
|
||||
- name: user-service
|
||||
url: http://user-service:3001
|
||||
routes:
|
||||
- name: user-routes
|
||||
paths:
|
||||
- /api/users
|
||||
strip_path: false
|
||||
methods:
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
- DELETE
|
||||
plugins:
|
||||
- name: jwt
|
||||
config:
|
||||
key_claim_name: kid
|
||||
secret_is_base64: false
|
||||
- name: rate-limiting
|
||||
config:
|
||||
minute: 100
|
||||
hour: 10000
|
||||
policy: local
|
||||
- name: request-transformer
|
||||
config:
|
||||
add:
|
||||
headers:
|
||||
- X-Gateway:Kong
|
||||
- X-Service:user-service
|
||||
|
||||
- name: product-service
|
||||
url: http://product-service:3002
|
||||
routes:
|
||||
- name: product-routes
|
||||
paths:
|
||||
- /api/products
|
||||
plugins:
|
||||
- name: rate-limiting
|
||||
config:
|
||||
minute: 200
|
||||
policy: redis
|
||||
redis_host: redis
|
||||
redis_port: 6379
|
||||
- name: cors
|
||||
config:
|
||||
origins:
|
||||
- https://app.example.com
|
||||
methods:
|
||||
- GET
|
||||
- POST
|
||||
headers:
|
||||
- Accept
|
||||
- Content-Type
|
||||
credentials: true
|
||||
- name: prometheus
|
||||
|
||||
upstreams:
|
||||
- name: user-service
|
||||
algorithm: round-robin
|
||||
targets:
|
||||
- target: user-service-1:3001
|
||||
weight: 100
|
||||
- target: user-service-2:3001
|
||||
weight: 100
|
||||
healthchecks:
|
||||
active:
|
||||
healthy:
|
||||
interval: 10
|
||||
successes: 3
|
||||
unhealthy:
|
||||
interval: 5
|
||||
http_failures: 3
|
||||
|
||||
plugins:
|
||||
- name: correlation-id
|
||||
config:
|
||||
header_name: X-Request-ID
|
||||
generator: uuid
|
||||
- name: request-size-limiting
|
||||
config:
|
||||
allowed_payload_size: 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 3: API Composition and Response Aggregation
|
||||
|
||||
**Scenario:** Gateway that combines multiple service responses
|
||||
|
||||
**Generated API Composition:**
|
||||
```javascript
|
||||
// gateway/api-composer.js
|
||||
class APIComposer {
|
||||
async composeUserProfile(userId, req) {
|
||||
// Parallel requests to multiple services
|
||||
const [user, orders, preferences, recommendations] = await Promise.allSettled([
|
||||
this.fetchUser(userId, req.headers),
|
||||
this.fetchUserOrders(userId, req.headers),
|
||||
this.fetchUserPreferences(userId, req.headers),
|
||||
this.fetchRecommendations(userId, req.headers)
|
||||
]);
|
||||
|
||||
// Compose response with error handling
|
||||
const profile = {
|
||||
user: user.status === 'fulfilled' ? user.value : null,
|
||||
orders: orders.status === 'fulfilled' ? orders.value : [],
|
||||
preferences: preferences.status === 'fulfilled' ? preferences.value : {},
|
||||
recommendations: recommendations.status === 'fulfilled' ? recommendations.value : []
|
||||
};
|
||||
|
||||
// Add metadata
|
||||
profile._meta = {
|
||||
composed_at: new Date().toISOString(),
|
||||
partial: Object.values(profile).some(v => v === null || v === undefined),
|
||||
services: {
|
||||
user: user.status,
|
||||
orders: orders.status,
|
||||
preferences: preferences.status,
|
||||
recommendations: recommendations.status
|
||||
}
|
||||
};
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
async fetchWithTimeout(url, options, timeout = 3000) {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
signal: controller.signal
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
return response.json();
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Error: Service Unavailable
|
||||
**Symptoms:** 503 errors, timeouts
|
||||
**Cause:** Backend service down or overloaded
|
||||
**Solution:**
|
||||
```javascript
|
||||
// Implement circuit breaker and fallback
|
||||
breaker.fallback(() => ({
|
||||
data: [],
|
||||
source: 'cache',
|
||||
message: 'Using cached data due to service unavailability'
|
||||
}));
|
||||
```
|
||||
**Prevention:** Health checks, circuit breakers, graceful degradation
|
||||
|
||||
### Error: Authentication Failures
|
||||
**Symptoms:** High rate of 401/403 errors
|
||||
**Cause:** Token expiry, invalid credentials, or permission issues
|
||||
**Solution:** Implement token refresh mechanism and clear error messages
|
||||
|
||||
### Error: Rate Limit Exceeded
|
||||
**Symptoms:** 429 Too Many Requests
|
||||
**Cause:** Client exceeding configured limits
|
||||
**Solution:** Implement backoff strategy and provide rate limit headers
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Option: `--framework`
|
||||
- **Purpose:** Choose gateway framework
|
||||
- **Values:** `kong`, `express-gateway`, `custom`, `aws-api-gateway`
|
||||
- **Default:** `custom`
|
||||
- **Example:** `/gateway --framework kong`
|
||||
|
||||
### Option: `--auth`
|
||||
- **Purpose:** Authentication method
|
||||
- **Values:** `jwt`, `oauth2`, `api-key`, `basic`, `none`
|
||||
- **Default:** `jwt`
|
||||
- **Example:** `/gateway --auth oauth2`
|
||||
|
||||
### Option: `--load-balancer`
|
||||
- **Purpose:** Load balancing algorithm
|
||||
- **Values:** `round-robin`, `least-connections`, `weighted`, `ip-hash`
|
||||
- **Default:** `round-robin`
|
||||
- **Example:** `/gateway --load-balancer weighted`
|
||||
|
||||
## Best Practices
|
||||
|
||||
✅ **DO:**
|
||||
- Implement circuit breakers for all backend services
|
||||
- Use correlation IDs for request tracing
|
||||
- Cache responses where appropriate
|
||||
- Monitor gateway performance metrics
|
||||
- Implement graceful degradation strategies
|
||||
|
||||
❌ **DON'T:**
|
||||
- Perform heavy business logic in the gateway
|
||||
- Store state in the gateway (keep it stateless)
|
||||
- Ignore security headers and CORS configuration
|
||||
- Mix internal and external APIs on same gateway
|
||||
|
||||
💡 **TIPS:**
|
||||
- Use API composition sparingly to avoid gateway bottleneck
|
||||
- Implement request/response transformation close to services when possible
|
||||
- Consider GraphQL gateway for complex data aggregation needs
|
||||
- Use service mesh for internal service communication
|
||||
|
||||
## Related Commands
|
||||
|
||||
- `/api-rate-limiter` - Dedicated rate limiting setup
|
||||
- `/api-monitoring-dashboard` - Gateway monitoring
|
||||
- `/service-mesh-configurator` - Internal service communication
|
||||
- `/load-balancer-configurator` - Advanced load balancing
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Latency overhead:** 5-20ms per request typically
|
||||
- **Memory usage:** ~200MB base + 10MB per 1000 concurrent connections
|
||||
- **CPU usage:** Scales linearly with request rate
|
||||
- **Network:** Consider gateway placement for minimal hops
|
||||
|
||||
## Security Notes
|
||||
|
||||
⚠️ **Security Considerations:**
|
||||
- Always use HTTPS/TLS for external traffic
|
||||
- Implement DDoS protection at gateway level
|
||||
- Validate and sanitize all incoming requests
|
||||
- Never log sensitive data (tokens, passwords)
|
||||
- Use API key rotation and token expiration
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: High gateway latency
|
||||
**Solution:** Check service response times, reduce middleware chain, enable caching
|
||||
|
||||
### Issue: Memory leaks
|
||||
**Solution:** Monitor event listeners, implement proper cleanup, limit request body size
|
||||
|
||||
### Issue: Inconsistent routing
|
||||
**Solution:** Review route precedence, check path matching patterns
|
||||
|
||||
### Getting Help
|
||||
- Kong documentation: https://docs.konghq.com
|
||||
- Express Gateway: https://www.express-gateway.io/docs
|
||||
- API Gateway patterns: https://microservices.io/patterns/apigateway.html
|
||||
|
||||
## Version History
|
||||
|
||||
- **v2.0.0** - Complete rewrite with multiple framework support and API composition
|
||||
- **v1.0.0** - Initial Express-only implementation
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-10-11*
|
||||
*Quality score: 9.5/10*
|
||||
*Tested with: Kong 2.8, Express Gateway 1.16, Node.js 18*
|
||||
93
plugin.lock.json
Normal file
93
plugin.lock.json
Normal file
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:jeremylongshore/claude-code-plugins-plus:plugins/api-development/api-gateway-builder",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "5c1a66664a5a7fee25076c70ea0b56df02efebed",
|
||||
"treeHash": "3ad28ab94e5c1d2022a3feb5652a0b243f72693679a83918ad772c5e148abee2",
|
||||
"generatedAt": "2025-11-28T10:18:06.668572Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "api-gateway-builder",
|
||||
"description": "Build API gateway with routing, authentication, and rate limiting",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "34d7afbf3d3576ec473a5971947be1b9291d81e1dd03fd1e5093159014c95804"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "0fc7f871dcc470164db61f6bdf1877a76380ff35e86d58657cfded928bf2ea70"
|
||||
},
|
||||
{
|
||||
"path": "commands/build-api-gateway.md",
|
||||
"sha256": "0300e9d744343f948aac3471b139748dd4c51652c2e5dd9e5383265df1c17048"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/references/examples.md",
|
||||
"sha256": "922bbc3c4ebf38b76f515b5c1998ebde6bf902233e00e2c5a0e9176f975a7572"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/references/best-practices.md",
|
||||
"sha256": "c8f32b3566252f50daacd346d7045a1060c718ef5cfb07c55a0f2dec5f1fb39e"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/references/README.md",
|
||||
"sha256": "627041a8c57f4c823671d2d137de4803905cabceb7ec4cf887f705805ae2b413"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/scripts/helper-template.sh",
|
||||
"sha256": "0881d5660a8a7045550d09ae0acc15642c24b70de6f08808120f47f86ccdf077"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/scripts/validation.sh",
|
||||
"sha256": "92551a29a7f512d2036e4f1fb46c2a3dc6bff0f7dde4a9f699533e446db48502"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/scripts/README.md",
|
||||
"sha256": "f03d8086cc4a5e701e7cea4fc5bd93a7ec9f5fb993faeb2461669851d007b079"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/example_api_definition.json",
|
||||
"sha256": "5c231bdafff903f62a4d33e64ff4daf79de9f47632235e77d56cfdfde2b7ba11"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/test-data.json",
|
||||
"sha256": "ac17dca3d6e253a5f39f2a2f1b388e5146043756b05d9ce7ac53a0042eee139d"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/README.md",
|
||||
"sha256": "b270391ce2be45efd7b60325abb031b6ea490c195fbfff5265b2c8b8399bbf25"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/api_gateway_template.yaml",
|
||||
"sha256": "8449b9020e83e6a84c2e3d07a2f2138d57443cc11abd7761e709e141477b57e2"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/skill-schema.json",
|
||||
"sha256": "f5639ba823a24c9ac4fb21444c0717b7aefde1a4993682897f5bf544f863c2cd"
|
||||
},
|
||||
{
|
||||
"path": "skills/skill-adapter/assets/config-template.json",
|
||||
"sha256": "0c2ba33d2d3c5ccb266c0848fc43caa68a2aa6a80ff315d4b378352711f83e1c"
|
||||
}
|
||||
],
|
||||
"dirSha256": "3ad28ab94e5c1d2022a3feb5652a0b243f72693679a83918ad772c5e148abee2"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
7
skills/skill-adapter/assets/README.md
Normal file
7
skills/skill-adapter/assets/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Assets
|
||||
|
||||
Bundled resources for api-gateway-builder skill
|
||||
|
||||
- [ ] api_gateway_template.yaml: YAML template for defining API gateway configurations.
|
||||
- [ ] example_api_definition.json: Example API definition file.
|
||||
- [ ] error_response_templates/: Directory containing templates for different error responses (e.g., 400, 401, 500).
|
||||
55
skills/skill-adapter/assets/api_gateway_template.yaml
Normal file
55
skills/skill-adapter/assets/api_gateway_template.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
# API Gateway Configuration Template
|
||||
|
||||
# Gateway Metadata
|
||||
name: my-api-gateway # Name of the API gateway
|
||||
description: Production-ready API gateway configuration. # Description of the gateway
|
||||
|
||||
# Global Configuration
|
||||
global:
|
||||
# Default rate limit for all routes (requests per minute)
|
||||
default_rate_limit: 60 # Requests per minute
|
||||
# Enable/Disable global CORS settings. Set to 'true' or 'false'.
|
||||
enable_cors: true
|
||||
# Allowed origins for CORS (e.g., ['https://example.com', 'https://another.com', '*'])
|
||||
cors_allowed_origins: ['*'] # REPLACE_ME: List of allowed origins
|
||||
# Allowed methods for CORS (e.g., ['GET', 'POST', 'PUT', 'DELETE'])
|
||||
cors_allowed_methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
|
||||
# Allowed headers for CORS (e.g., ['Content-Type', 'Authorization'])
|
||||
cors_allowed_headers: ['Content-Type', 'Authorization', 'YOUR_HEADER_HERE']
|
||||
# Expose headers for CORS (e.g., ['Content-Type', 'Authorization'])
|
||||
cors_exposed_headers: ['Content-Type', 'Authorization']
|
||||
|
||||
# Authentication Configuration
|
||||
authentication:
|
||||
# Authentication type: 'jwt' or 'none'
|
||||
type: jwt
|
||||
jwt:
|
||||
# JWT secret key (used for verifying signatures)
|
||||
secret: REPLACE_ME # JWT Secret Key
|
||||
# Audience (optional)
|
||||
audience: YOUR_VALUE_HERE # JWT Audience
|
||||
# Issuer (optional)
|
||||
issuer: YOUR_VALUE_HERE # JWT Issuer
|
||||
|
||||
# Routes Configuration
|
||||
routes:
|
||||
- path: /users # Path for the route
|
||||
method: GET # HTTP method (GET, POST, PUT, DELETE, etc.)
|
||||
upstream_url: http://users-service:8080 # URL of the upstream service
|
||||
rate_limit: 120 # Route-specific rate limit (overrides global default)
|
||||
authentication_required: true # Requires authentication for this route
|
||||
# Optional plugins to apply to this route
|
||||
plugins:
|
||||
- name: circuit-breaker
|
||||
config:
|
||||
failure_threshold: 5
|
||||
recovery_timeout: 30
|
||||
- path: /products
|
||||
method: POST
|
||||
upstream_url: http://products-service:8080
|
||||
rate_limit: 60
|
||||
authentication_required: true
|
||||
- path: /public
|
||||
method: GET
|
||||
upstream_url: http://public-service:8080
|
||||
authentication_required: false # Public route, no authentication required
|
||||
32
skills/skill-adapter/assets/config-template.json
Normal file
32
skills/skill-adapter/assets/config-template.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"skill": {
|
||||
"name": "skill-name",
|
||||
"version": "1.0.0",
|
||||
"enabled": true,
|
||||
"settings": {
|
||||
"verbose": false,
|
||||
"autoActivate": true,
|
||||
"toolRestrictions": true
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"keywords": [
|
||||
"example-trigger-1",
|
||||
"example-trigger-2"
|
||||
],
|
||||
"patterns": []
|
||||
},
|
||||
"tools": {
|
||||
"allowed": [
|
||||
"Read",
|
||||
"Grep",
|
||||
"Bash"
|
||||
],
|
||||
"restricted": []
|
||||
},
|
||||
"metadata": {
|
||||
"author": "Plugin Author",
|
||||
"category": "general",
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
104
skills/skill-adapter/assets/example_api_definition.json
Normal file
104
skills/skill-adapter/assets/example_api_definition.json
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"_comment": "Example API Definition - Use this as a template for your API gateway configuration.",
|
||||
"api_name": "MyAwesomeAPI",
|
||||
"version": "v1",
|
||||
"base_path": "/api/v1",
|
||||
"authentication": {
|
||||
"_comment": "Authentication configuration. 'jwt' is currently the only supported method.",
|
||||
"type": "jwt",
|
||||
"jwt": {
|
||||
"_comment": "JWT specific configuration.",
|
||||
"issuer": "https://my-auth-server.example.com",
|
||||
"jwks_uri": "https://my-auth-server.example.com/.well-known/jwks.json",
|
||||
"audience": "my-api-audience"
|
||||
}
|
||||
},
|
||||
"rate_limiting": {
|
||||
"_comment": "Global rate limiting configuration. Applies to all routes.",
|
||||
"enabled": true,
|
||||
"requests_per_minute": 100,
|
||||
"burst_size": 200,
|
||||
"identifier": "ip"
|
||||
},
|
||||
"routes": [
|
||||
{
|
||||
"_comment": "Route for getting user details.",
|
||||
"path": "/users/{user_id}",
|
||||
"method": "GET",
|
||||
"target_url": "http://user-service.example.com/users/{user_id}",
|
||||
"authentication_required": true,
|
||||
"rate_limiting": {
|
||||
"_comment": "Override global rate limiting for this route.",
|
||||
"enabled": true,
|
||||
"requests_per_minute": 20,
|
||||
"burst_size": 40,
|
||||
"identifier": "user_id"
|
||||
},
|
||||
"circuit_breaker": {
|
||||
"_comment": "Circuit breaker configuration for this route.",
|
||||
"enabled": true,
|
||||
"error_threshold_percentage": 50,
|
||||
"reset_timeout_ms": 30000,
|
||||
"volume_threshold": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"_comment": "Route for creating a new user.",
|
||||
"path": "/users",
|
||||
"method": "POST",
|
||||
"target_url": "http://user-service.example.com/users",
|
||||
"authentication_required": false,
|
||||
"rate_limiting": {
|
||||
"_comment": "Use global rate limiting."
|
||||
},
|
||||
"circuit_breaker": {
|
||||
"_comment": "Use global circuit breaker settings or disable circuit breaker",
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"_comment": "Route for listing all products.",
|
||||
"path": "/products",
|
||||
"method": "GET",
|
||||
"target_url": "http://product-service.example.com/products",
|
||||
"authentication_required": true,
|
||||
"rate_limiting": {
|
||||
"_comment": "Override global rate limiting for this route.",
|
||||
"enabled": true,
|
||||
"requests_per_minute": 50,
|
||||
"burst_size": 100,
|
||||
"identifier": "ip"
|
||||
},
|
||||
"circuit_breaker": {
|
||||
"_comment": "Circuit breaker configuration for this route.",
|
||||
"enabled": true,
|
||||
"error_threshold_percentage": 50,
|
||||
"reset_timeout_ms": 30000,
|
||||
"volume_threshold": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"_comment": "Route for health check.",
|
||||
"path": "/health",
|
||||
"method": "GET",
|
||||
"target_url": "http://health-service.example.com/health",
|
||||
"authentication_required": false,
|
||||
"rate_limiting": {
|
||||
"_comment": "No rate limiting for health check.",
|
||||
"enabled": false
|
||||
},
|
||||
"circuit_breaker": {
|
||||
"_comment": "Disable circuit breaker for health check",
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"load_balancing": {
|
||||
"_comment": "Load balancing configuration",
|
||||
"algorithm": "round_robin",
|
||||
"targets": [
|
||||
"http://user-service-instance1.example.com",
|
||||
"http://user-service-instance2.example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
28
skills/skill-adapter/assets/skill-schema.json
Normal file
28
skills/skill-adapter/assets/skill-schema.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Claude Skill Configuration",
|
||||
"type": "object",
|
||||
"required": ["name", "description"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9-]+$",
|
||||
"maxLength": 64,
|
||||
"description": "Skill identifier (lowercase, hyphens only)"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"maxLength": 1024,
|
||||
"description": "What the skill does and when to use it"
|
||||
},
|
||||
"allowed-tools": {
|
||||
"type": "string",
|
||||
"description": "Comma-separated list of allowed tools"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
||||
"description": "Semantic version (x.y.z)"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
skills/skill-adapter/assets/test-data.json
Normal file
27
skills/skill-adapter/assets/test-data.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"testCases": [
|
||||
{
|
||||
"name": "Basic activation test",
|
||||
"input": "trigger phrase example",
|
||||
"expected": {
|
||||
"activated": true,
|
||||
"toolsUsed": ["Read", "Grep"],
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Complex workflow test",
|
||||
"input": "multi-step trigger example",
|
||||
"expected": {
|
||||
"activated": true,
|
||||
"steps": 3,
|
||||
"toolsUsed": ["Read", "Write", "Bash"],
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"fixtures": {
|
||||
"sampleInput": "example data",
|
||||
"expectedOutput": "processed result"
|
||||
}
|
||||
}
|
||||
9
skills/skill-adapter/references/README.md
Normal file
9
skills/skill-adapter/references/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# References
|
||||
|
||||
Bundled resources for api-gateway-builder skill
|
||||
|
||||
- [ ] api_gateway_best_practices.md: Documentation on best practices for designing and building API gateways.
|
||||
- [ ] jwt_authentication_guide.md: Detailed guide on implementing JWT authentication in the API gateway.
|
||||
- [ ] rate_limiting_strategies.md: Explanation of different rate limiting strategies and how to implement them.
|
||||
- [ ] microservice_integration_guide.md: Guide on integrating microservices with the API gateway.
|
||||
- [ ] api_gateway_schema.json: JSON schema defining the structure of API gateway configurations.
|
||||
69
skills/skill-adapter/references/best-practices.md
Normal file
69
skills/skill-adapter/references/best-practices.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Skill Best Practices
|
||||
|
||||
Guidelines for optimal skill usage and development.
|
||||
|
||||
## For Users
|
||||
|
||||
### Activation Best Practices
|
||||
|
||||
1. **Use Clear Trigger Phrases**
|
||||
- Match phrases from skill description
|
||||
- Be specific about intent
|
||||
- Provide necessary context
|
||||
|
||||
2. **Provide Sufficient Context**
|
||||
- Include relevant file paths
|
||||
- Specify scope of analysis
|
||||
- Mention any constraints
|
||||
|
||||
3. **Understand Tool Permissions**
|
||||
- Check allowed-tools in frontmatter
|
||||
- Know what the skill can/cannot do
|
||||
- Request appropriate actions
|
||||
|
||||
### Workflow Optimization
|
||||
|
||||
- Start with simple requests
|
||||
- Build up to complex workflows
|
||||
- Verify each step before proceeding
|
||||
- Use skill consistently for related tasks
|
||||
|
||||
## For Developers
|
||||
|
||||
### Skill Development Guidelines
|
||||
|
||||
1. **Clear Descriptions**
|
||||
- Include explicit trigger phrases
|
||||
- Document all capabilities
|
||||
- Specify limitations
|
||||
|
||||
2. **Proper Tool Permissions**
|
||||
- Use minimal necessary tools
|
||||
- Document security implications
|
||||
- Test with restricted tools
|
||||
|
||||
3. **Comprehensive Documentation**
|
||||
- Provide usage examples
|
||||
- Document common pitfalls
|
||||
- Include troubleshooting guide
|
||||
|
||||
### Maintenance
|
||||
|
||||
- Keep version updated
|
||||
- Test after tool updates
|
||||
- Monitor user feedback
|
||||
- Iterate on descriptions
|
||||
|
||||
## Performance Tips
|
||||
|
||||
- Scope skills to specific domains
|
||||
- Avoid overlapping trigger phrases
|
||||
- Keep descriptions under 1024 chars
|
||||
- Test activation reliability
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Never include secrets in skill files
|
||||
- Validate all inputs
|
||||
- Use read-only tools when possible
|
||||
- Document security requirements
|
||||
70
skills/skill-adapter/references/examples.md
Normal file
70
skills/skill-adapter/references/examples.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Skill Usage Examples
|
||||
|
||||
This document provides practical examples of how to use this skill effectively.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Example 1: Simple Activation
|
||||
|
||||
**User Request:**
|
||||
```
|
||||
[Describe trigger phrase here]
|
||||
```
|
||||
|
||||
**Skill Response:**
|
||||
1. Analyzes the request
|
||||
2. Performs the required action
|
||||
3. Returns results
|
||||
|
||||
### Example 2: Complex Workflow
|
||||
|
||||
**User Request:**
|
||||
```
|
||||
[Describe complex scenario]
|
||||
```
|
||||
|
||||
**Workflow:**
|
||||
1. Step 1: Initial analysis
|
||||
2. Step 2: Data processing
|
||||
3. Step 3: Result generation
|
||||
4. Step 4: Validation
|
||||
|
||||
## Advanced Patterns
|
||||
|
||||
### Pattern 1: Chaining Operations
|
||||
|
||||
Combine this skill with other tools:
|
||||
```
|
||||
Step 1: Use this skill for [purpose]
|
||||
Step 2: Chain with [other tool]
|
||||
Step 3: Finalize with [action]
|
||||
```
|
||||
|
||||
### Pattern 2: Error Handling
|
||||
|
||||
If issues occur:
|
||||
- Check trigger phrase matches
|
||||
- Verify context is available
|
||||
- Review allowed-tools permissions
|
||||
|
||||
## Tips & Best Practices
|
||||
|
||||
- ✅ Be specific with trigger phrases
|
||||
- ✅ Provide necessary context
|
||||
- ✅ Check tool permissions match needs
|
||||
- ❌ Avoid vague requests
|
||||
- ❌ Don't mix unrelated tasks
|
||||
|
||||
## Common Issues
|
||||
|
||||
**Issue:** Skill doesn't activate
|
||||
**Solution:** Use exact trigger phrases from description
|
||||
|
||||
**Issue:** Unexpected results
|
||||
**Solution:** Check input format and context
|
||||
|
||||
## See Also
|
||||
|
||||
- Main SKILL.md for full documentation
|
||||
- scripts/ for automation helpers
|
||||
- assets/ for configuration examples
|
||||
7
skills/skill-adapter/scripts/README.md
Normal file
7
skills/skill-adapter/scripts/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Scripts
|
||||
|
||||
Bundled resources for api-gateway-builder skill
|
||||
|
||||
- [ ] create_api_gateway.py: Automates the creation of API gateway configurations based on user input.
|
||||
- [ ] deploy_api_gateway.sh: Script to deploy the API gateway to a specified environment.
|
||||
- [ ] test_api_gateway.py: Script to run automated tests against the deployed API gateway.
|
||||
42
skills/skill-adapter/scripts/helper-template.sh
Executable file
42
skills/skill-adapter/scripts/helper-template.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# Helper script template for skill automation
|
||||
# Customize this for your skill's specific needs
|
||||
|
||||
set -e
|
||||
|
||||
function show_usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Show this help message"
|
||||
echo " -v, --verbose Enable verbose output"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
VERBOSE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Your skill logic here
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
echo "Running skill automation..."
|
||||
fi
|
||||
|
||||
echo "✅ Complete"
|
||||
32
skills/skill-adapter/scripts/validation.sh
Executable file
32
skills/skill-adapter/scripts/validation.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Skill validation helper
|
||||
# Validates skill activation and functionality
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔍 Validating skill..."
|
||||
|
||||
# Check if SKILL.md exists
|
||||
if [ ! -f "../SKILL.md" ]; then
|
||||
echo "❌ Error: SKILL.md not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate frontmatter
|
||||
if ! grep -q "^---$" "../SKILL.md"; then
|
||||
echo "❌ Error: No frontmatter found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check required fields
|
||||
if ! grep -q "^name:" "../SKILL.md"; then
|
||||
echo "❌ Error: Missing 'name' field"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q "^description:" "../SKILL.md"; then
|
||||
echo "❌ Error: Missing 'description' field"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Skill validation passed"
|
||||
Reference in New Issue
Block a user