Files
Pony-Alpha-2-Dataset-Training/agents/agent-api-architect.md
Pony Alpha 2 68453089ee feat: initial Alpha Brain 2 dataset release
Massive training corpus for AI coding models containing:
- 10 JSONL training datasets (641+ examples across coding, reasoning, planning, architecture, communication, debugging, security, workflows, error handling, UI/UX)
- 11 agent behavior specifications (explorer, planner, reviewer, debugger, executor, UI designer, Linux admin, kernel engineer, security architect, automation engineer, API architect)
- 6 skill definition files (coding, API engineering, kernel, Linux server, security architecture, server automation, UI/UX)
- Master README with project origin story and philosophy

Built by Pony Alpha 2 to help AI models learn expert-level coding approaches.
2026-03-13 16:26:29 +04:00

2373 lines
59 KiB
Markdown

# API Architect Agent
## Agent Purpose
The API Architect Agent specializes in designing, implementing, and optimizing APIs across various protocols (REST, GraphQL, gRPC) and use cases. This agent ensures APIs are scalable, secure, performant, and developer-friendly while following industry best practices and standards.
**Activation Criteria:**
- API design and architecture
- REST/GraphQL/gRPC API implementation
- API documentation and specification
- API security and authentication
- API performance optimization
- API versioning and lifecycle management
- SDK client development
- API testing and quality assurance
- API gateway configuration
- Webhook and event-driven API design
---
## Core Capabilities
### 1. API Design & Architecture
**API Design Methodology:**
```yaml
# API Design Framework
design_principles:
resource_oriented:
description: "Design around resources, not actions"
guidelines:
- use_nouns_for_resources: "users, orders, products"
- use_hierarchies_for_relationships: "/users/{id}/orders"
- avoid_action_verbs: "prefer GET /users/{id}/activate over POST /users/{id}/activate"
- use_plural_nouns: "consistently use plural form"
uniform_interface:
description: "Consistent interface across all endpoints"
guidelines:
- consistent_url_structure: "pattern across all resources"
- consistent_response_format: "standard response wrapper"
- consistent_error_handling: "uniform error responses"
- consistent_naming_conventions: "camelCase or snake_case"
stateless:
description: "No client context stored on server"
guidelines:
- include_all_needed_data: "client provides all context"
- use_tokens_for_state: "JWT for authentication"
- avoid_server-side_sessions: "store session state in token"
- design_for_scalability: "stateless enables horizontal scaling"
cacheable:
description: "Leverage HTTP caching where appropriate"
guidelines:
- use_cache_headers: "Cache-Control, ETag, Last-Modified"
- version_resources: "enable conditional requests"
- mark_safe_endpoints: "GET, HEAD can be cached"
- consider_cdn: "cache static content"
layered_system:
description: "Separate concerns across layers"
guidelines:
- api_gateway_layer: "routing, rate limiting, auth"
- service_layer: "business logic"
- data_layer: "database, external services"
- clear_boundaries: "well-defined interfaces"
code_on_demand:
description: "Optional executable code support"
guidelines:
- use_sparingly: "only when necessary"
- consider_webhooks: "as alternative"
- document_extensions: "clear API extensions"
- security_implications: "validate all code"
# API Design Process
design_process:
1_requirements_analysis:
activities:
- identify_use_cases: "Who will use the API and what for?"
- define_resources: "What entities does the API expose?"
- define_relationships: "How do resources relate?"
- identify_operations: "CRUD operations needed"
- consider_performance: "Latency, throughput requirements"
- consider_security: "Authentication, authorization needs"
2_resource_modeling:
activities:
- create_resource_hierarchy: "Define resource structure"
- define_resource_properties: "Attributes of each resource"
- establish_relationships: "One-to-many, many-to-many"
- define_query_parameters: "Filtering, sorting, pagination"
- define_sub_resources: "Nested resources"
3_endpoint_design:
activities:
- design_url_structure: "RESTful URLs"
- choose_http_methods: "GET, POST, PUT, PATCH, DELETE"
- define_request_bodies: "Request schemas"
- define_response_bodies: "Response schemas"
- define_status_codes: "Appropriate HTTP status codes"
- design_error_responses: "Error format and details"
4_security_design:
activities:
- choose_authentication: "API keys, OAuth2, JWT"
- choose_authorization: "RBAC, ABAC, scopes"
- define_rate_limits: "Per-user, per-key limits"
- design_input_validation: "Validate all inputs"
- plan_cors_policy: "Cross-origin access"
- consider_encryption: "HTTPS, encrypted payloads"
5_documentation:
activities:
- write_openapi_spec: "API specification"
- document_endpoints: "Detailed endpoint docs"
- provide_examples: "Request/response examples"
- create_tutorials: "Getting started guides"
- generate_sdks: "Client libraries"
6_testing_strategy:
activities:
- define_test_cases: "Unit, integration, E2E"
- design_mocks: "Mock servers for testing"
- performance_tests: "Load testing plans"
- security_tests: "Penetration testing"
- contract_tests: "API contract validation"
```
**RESTful API Design Patterns:**
```yaml
# REST API Endpoint Patterns
# Standard CRUD Endpoints
crud_endpoints:
users:
list:
method: GET
path: /api/v1/users
description: "List all users with pagination"
query_params:
- page: "Page number (default: 1)"
- per_page: "Items per page (default: 20, max: 100)"
- sort: "Sort field (e.g., 'created_at', 'name')"
- order: "Sort order: 'asc' or 'desc'"
- filter: "Filter by field (e.g., 'status=active')"
response:
status: 200
body:
data: "Array of user objects"
pagination:
page: 1
per_page: 20
total_pages: 50
total_count: 1000
retrieve:
method: GET
path: /api/v1/users/{id}
description: "Get a specific user by ID"
response:
status: 200
body:
data:
id: "user123"
name: "John Doe"
email: "john@example.com"
created_at: "2024-01-15T10:30:00Z"
updated_at: "2024-01-15T10:30:00Z"
create:
method: POST
path: /api/v1/users
description: "Create a new user"
request:
body:
name: "John Doe"
email: "john@example.com"
password: "SecurePassword123!"
response:
status: 201
body:
data:
id: "user123"
name: "John Doe"
email: "john@example.com"
created_at: "2024-01-15T10:30:00Z"
update:
method: PUT
path: /api/v1/users/{id}
description: "Replace entire user resource"
request:
body:
name: "John Smith"
email: "john.smith@example.com"
response:
status: 200
body:
data:
id: "user123"
name: "John Smith"
email: "john.smith@example.com"
updated_at: "2024-01-15T11:00:00Z"
partial_update:
method: PATCH
path: /api/v1/users/{id}
description: "Update specific user fields"
request:
body:
name: "John Smith"
response:
status: 200
body:
data:
id: "user123"
name: "John Smith"
email: "john@example.com"
updated_at: "2024-01-15T11:00:00Z"
delete:
method: DELETE
path: /api/v1/users/{id}
description: "Delete a user"
response:
status: 204
body: null
# Nested Resources
nested_resources:
user_orders:
list:
method: GET
path: /api/v1/users/{user_id}/orders
description: "Get orders for a specific user"
create:
method: POST
path: /api/v1/users/{user_id}/orders
description: "Create an order for a specific user"
# Action Endpoints (when CRUD doesn't fit)
action_endpoints:
user_activation:
activate:
method: POST
path: /api/v1/users/{id}/activate
description: "Activate a user account"
deactivate:
method: POST
path: /api/v1/users/{id}/deactivate
description: "Deactivate a user account"
password_reset:
request:
method: POST
path: /api/v1/password-reset/request
description: "Request password reset email"
confirm:
method: POST
path: /api/v1/password-reset/confirm
description: "Confirm password reset with token"
# Search Endpoints
search_endpoints:
search:
method: GET
path: /api/v1/search
description: "Search across multiple resource types"
query_params:
- q: "Search query"
- type: "Resource type filter (users, products, orders)"
- page: "Page number"
- per_page: "Items per page"
response:
status: 200
body:
data:
users: []
products: []
orders: []
```
**GraphQL API Design:**
```graphql
# GraphQL Schema Design
# Schema Definition
type User {
id: ID!
email: String!
name: String!
status: UserStatus!
createdAt: DateTime!
updatedAt: DateTime!
# Relationships
orders(first: Int, after: String, status: OrderStatus): OrderConnection!
profile: UserProfile
permissions: [Permission!]!
# Computed fields
fullName: String! @deprecated(reason: "Use 'name' field instead")
isActive: Boolean!
}
type Order {
id: ID!
userId: ID!
user: User!
items: [OrderItem!]!
total: Decimal!
status: OrderStatus!
createdAt: DateTime!
updatedAt: DateTime!
# Computed fields
itemCount: Int!
isPaid: Boolean!
canCancel: Boolean!
}
type OrderItem {
id: ID!
orderId: ID!
productId: ID!
product: Product!
quantity: Int!
price: Decimal!
subtotal: Decimal!
}
type Product {
id: ID!
name: String!
description: String
price: Decimal!
sku: String!
inventory: Int!
categories: [Category!]!
images: [ProductImage!]!
createdAt: DateTime!
updatedAt: DateTime!
# Computed fields
inStock: Boolean!
discountPrice: Decimal
rating: Float
}
type Category {
id: ID!
name: String!
slug: String!
description: String
parent: Category
children: [Category!]!
products(first: Int, after: String): ProductConnection!
}
# Enums
enum UserStatus {
ACTIVE
INACTIVE
SUSPENDED
PENDING
}
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
REFUNDED
}
# Connection Pattern (Pagination)
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type UserEdge {
node: User!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
type ProductConnection {
edges: [ProductEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type ProductEdge {
node: Product!
cursor: String!
}
type OrderConnection {
edges: [OrderEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type OrderEdge {
node: Order!
cursor: String!
}
# Input Types
input CreateUserInput {
email: String!
name: String!
password: String!
profile: UserProfileInput
}
input UpdateUserInput {
email: String
name: String
status: UserStatus
profile: UserProfileInput
}
input UserProfileInput {
firstName: String
lastName: String
phone: String
address: AddressInput
}
input AddressInput {
street: String!
city: String!
state: String!
postalCode: String!
country: String!
}
input CreateOrderInput {
items: [OrderItemInput!]!
shippingAddress: AddressInput!
billingAddress: AddressInput
}
input OrderItemInput {
productId: ID!
quantity: Int!
}
# Queries
type Query {
# User queries
user(id: ID!): User
users(
first: Int
after: String
filter: UserFilterInput
sort: UserSortInput
): UserConnection!
me: User
# Product queries
product(id: ID!, slug: String): Product
products(
first: Int
after: String
filter: ProductFilterInput
sort: ProductSortInput
): ProductConnection!
category(id: ID!, slug: String): Category
categories: [Category!]!
# Order queries
order(id: ID!): Order
orders(
first: Int
after: String
filter: OrderFilterInput
sort: OrderSortInput
): OrderConnection!
myOrders(
first: Int
after: String
status: OrderStatus
): OrderConnection!
# Search
search(query: String!, types: [SearchType!], first: Int): SearchResult!
}
# Mutations
type Mutation {
# User mutations
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
deleteUser(id: ID!): DeleteUserPayload!
# Order mutations
createOrder(input: CreateOrderInput!): CreateOrderPayload!
cancelOrder(id: ID!): CancelOrderPayload!
refundOrder(id: ID!, reason: String): RefundOrderPayload!
# Product mutations
createProduct(input: CreateProductInput!): CreateProductPayload!
updateProduct(id: ID!, input: UpdateProductInput!): UpdateProductPayload!
deleteProduct(id: ID!): DeleteProductPayload!
# Authentication
login(email: String!, password: String!): AuthPayload!
logout: Boolean!
refreshToken(token: String!): AuthPayload!
}
# Subscriptions
type Subscription {
orderUpdated(userId: ID!): Order!
productUpdated(categoryIds: [ID!]): Product!
notificationReceived(userId: ID!): Notification!
}
# Payload Types (Response Wrappers)
type CreateUserPayload {
user: User
errors: [UserError!]!
success: Boolean!
}
type UserError {
field: String
message: String!
}
type AuthPayload {
token: String!
refreshToken: String!
user: User!
errors: [UserError!]!
success: Boolean!
}
type SearchResult {
users: [User!]!
products: [Product!]!
orders: [Order!]!
totalCount: Int!
}
# Custom Scalars
scalar DateTime
scalar Decimal
```
**gRPC API Design:**
```protobuf
// gRPC Service Definitions
syntax = "proto3";
package api.v1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
import "validate/validate.proto";
// User Service
service UserService {
// Get a user by ID
rpc GetUser(GetUserRequest) returns (User) {
option (google.api.http) = {
get: "/api/v1/users/{user_id}"
};
}
// List users with pagination
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {
option (google.api.http) = {
get: "/api/v1/users"
};
}
// Create a new user
rpc CreateUser(CreateUserRequest) returns (User) {
option (google.api.http) = {
post: "/api/v1/users"
body: "*"
};
}
// Update a user
rpc UpdateUser(UpdateUserRequest) returns (User) {
option (google.api.http) = {
patch: "/api/v1/users/{user_id}"
body: "*"
};
}
// Delete a user
rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/api/v1/users/{user_id}"
};
}
}
// Order Service
service OrderService {
rpc CreateOrder(CreateOrderRequest) returns (Order) {
option (google.api.http) = {
post: "/api/v1/orders"
body: "*"
};
}
rpc GetOrder(GetOrderRequest) returns (Order) {
option (google.api.http) = {
get: "/api/v1/orders/{order_id}"
};
}
rpc ListOrders(ListOrdersRequest) returns (ListOrdersResponse) {
option (google.api.http) = {
get: "/api/v1/orders"
};
}
rpc CancelOrder(CancelOrderRequest) returns (Order) {
option (google.api.http) = {
post: "/api/v1/orders/{order_id}:cancel"
body: "*"
};
}
// Server-side streaming for real-time updates
rpc StreamOrderUpdates(StreamOrderUpdatesRequest) returns (stream Order);
}
// Product Service
service ProductService {
rpc GetProduct(GetProductRequest) returns (Product) {
option (google.api.http) = {
get: "/api/v1/products/{product_id}"
};
}
rpc ListProducts(ListProductsRequest) returns (ListProductsResponse) {
option (google.api.http) = {
get: "/api/v1/products"
};
}
rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {
option (google.api.http) = {
get: "/api/v1/products:search"
};
}
}
// Messages
message User {
string user_id = 1;
string email = 2;
string name = 3;
UserStatus status = 4;
google.protobuf.Timestamp created_at = 5;
google.protobuf.Timestamp updated_at = 6;
UserProfile profile = 7;
}
message UserProfile {
string first_name = 1;
string last_name = 2;
string phone = 3;
Address address = 4;
}
message Address {
string street = 1;
string city = 2;
string state = 3;
string postal_code = 4;
string country = 5;
}
enum UserStatus {
USER_STATUS_UNSPECIFIED = 0;
USER_STATUS_ACTIVE = 1;
USER_STATUS_INACTIVE = 2;
USER_STATUS_SUSPENDED = 3;
USER_STATUS_PENDING = 4;
}
message Order {
string order_id = 1;
string user_id = 2;
repeated OrderItem items = 3;
double total = 4;
OrderStatus status = 5;
google.protobuf.Timestamp created_at = 6;
google.protobuf.Timestamp updated_at = 7;
Address shipping_address = 8;
Address billing_address = 9;
}
message OrderItem {
string order_item_id = 1;
string product_id = 2;
int32 quantity = 3;
double price = 4;
double subtotal = 5;
}
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_PROCESSING = 2;
ORDER_STATUS_SHIPPED = 3;
ORDER_STATUS_DELIVERED = 4;
ORDER_STATUS_CANCELLED = 5;
ORDER_STATUS_REFUNDED = 6;
}
message Product {
string product_id = 1;
string name = 2;
string description = 3;
double price = 4;
string sku = 5;
int32 inventory = 6;
repeated string category_ids = 7;
google.protobuf.Timestamp created_at = 8;
google.protobuf.Timestamp updated_at = 9;
}
// Request Messages
message GetUserRequest {
string user_id = 1 [(validate.rules).string.min_len = 1];
}
message ListUsersRequest {
int32 page_size = 1 [(validate.rules).int32 = {gte: 1, lte: 100}];
string page_token = 2;
string filter = 3; // Simple filter string
string sort_by = 4; // Sort field
bool sort_ascending = 5;
}
message ListUsersResponse {
repeated User users = 1;
string next_page_token = 2;
int32 total_count = 3;
}
message CreateUserRequest {
string email = 1 [(validate.rules).string.email = true];
string name = 2 [(validate.rules).string.min_len = 1];
string password = 3 [(validate.rules).string.min_len = 8];
UserProfile profile = 4;
}
message UpdateUserRequest {
string user_id = 1 [(validate.rules).string.min_len = 1];
string email = 2 [(validate.rules).string.email = true];
string name = 3;
UserStatus status = 4;
UserProfile profile = 5;
}
message DeleteUserRequest {
string user_id = 1 [(validate.rules).string.min_len = 1];
}
message CreateOrderRequest {
string user_id = 1 [(validate.rules).string.min_len = 1];
repeated CreateOrderItem items = 2 [(validate.rules).repeated.min_items = 1];
Address shipping_address = 3 [(validate.rules).message.required = true];
Address billing_address = 4;
}
message CreateOrderItem {
string product_id = 1 [(validate.rules).string.min_len = 1];
int32 quantity = 2 [(validate.rules).int32.gte = 1];
}
message GetOrderRequest {
string order_id = 1 [(validate.rules).string.min_len = 1];
}
message ListOrdersRequest {
string user_id = 1;
int32 page_size = 2 [(validate.rules).int32 = {gte: 1, lte: 100}];
string page_token = 3;
OrderStatus status = 4;
}
message ListOrdersResponse {
repeated Order orders = 1;
string next_page_token = 2;
int32 total_count = 3;
}
message CancelOrderRequest {
string order_id = 1 [(validate.rules).string.min_len = 1];
string reason = 2;
}
message StreamOrderUpdatesRequest {
string user_id = 1 [(validate.rules).string.min_len = 1];
google.protobuf.Timestamp since = 2;
}
```
### 2. API Security Implementation
**Authentication & Authorization:**
```yaml
# API Security Architecture
authentication_strategies:
api_key_authentication:
description: "Simple API key in header"
implementation:
header_name: "X-API-Key"
key_format: "UUID or random string"
storage: "Hashed in database"
validation: "Check on every request"
use_cases:
- "Service-to-service communication"
- "Simple integrations"
- "Internal APIs"
security_considerations:
- "Should be used with HTTPS"
- "Revoke compromised keys immediately"
- "Implement rate limiting per key"
- "Rotate keys periodically"
oauth2_authentication:
description: "OAuth 2.0 authorization framework"
implementation:
grant_types:
- authorization_code: "For third-party applications"
- client_credentials: "For service-to-service"
- refresh_token: "For obtaining new access tokens"
token_format: "JWT"
token_expiry: "3600 seconds"
endpoints:
authorization: "/oauth/authorize"
token: "/oauth/token"
refresh: "/oauth/refresh"
revoke: "/oauth/revoke"
use_cases:
- "User-facing applications"
- "Third-party integrations"
- "Mobile applications"
security_considerations:
- "Implement PKCE for public clients"
- "Store tokens securely"
- "Implement token revocation"
- "Use short-lived tokens"
jwt_authentication:
description: "JSON Web Tokens for stateless authentication"
implementation:
algorithm: "RS256" # Asymmetric
secret: "Or HS256 (symmetric) for simpler setups"
payload:
sub: "User ID"
iat: "Issued at"
exp: "Expiration"
iss: "Issuer"
aud: "Audience"
scopes: "Permission scopes"
header: "Authorization: Bearer {token}"
use_cases:
- "Stateless APIs"
- "Microservices"
- "Mobile applications"
security_considerations:
- "Sign tokens with strong keys"
- "Validate all claims"
- "Implement token expiration"
- "Use refresh tokens"
authorization_models:
role_based_access_control:
description: "Access based on user roles"
implementation:
roles:
- admin: "Full access"
- user: "Limited access"
- guest: "Read-only access"
permissions:
- users:read: "List, view users"
- users:write: "Create, update, delete users"
- orders:read: "List, view orders"
- orders:write: "Create, update, cancel orders"
role_permissions:
admin: ["*"]
user: ["users:read", "orders:read", "orders:write"]
guest: ["users:read", "orders:read"]
middleware:
check_permissions: "Verify user has required permissions"
require_authentication: "Ensure user is authenticated"
require_role: "Ensure user has required role"
attribute_based_access_control:
description: "Access based on user attributes and resource attributes"
implementation:
user_attributes:
- department: "User's department"
- location: "User's location"
- level: "User's level (junior, senior, lead)"
resource_attributes:
- owner: "Resource owner"
- department: "Resource's department"
- classification: "Resource classification (public, internal, confidential)"
policies:
- name: "Users can access their own resources"
condition: "user.id == resource.owner_id"
- name: "Managers can access department resources"
condition: "user.department == resource.department && user.level == 'manager'"
- name: "Confidential resources require specific clearance"
condition: "resource.classification == 'confidential' => user.clearance >= 'confidential'"
scope_based_access_control:
description: "Access based on OAuth scopes"
implementation:
scopes:
- read:users: "Read user information"
- write:users: "Create, update, delete users"
- read:orders: "Read order information"
- write:orders: "Create, update, cancel orders"
- admin: "Full administrative access"
scope_assignment:
- user_read: ["read:users"]
- user_write: ["read:users", "write:users"]
- order_read: ["read:orders"]
- order_write: ["read:orders", "write:orders"]
- admin: ["admin"]
middleware:
require_scopes: "Verify token has required scopes"
```
**API Security Implementation (Express.js):**
```typescript
// API Security Middleware Implementation
import express from 'express';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
import cors from 'cors';
// Security Headers
export function setupSecurityHeaders(app: express.Application) {
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", 'data:', 'https:'],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
noSniff: true,
xssFilter: true,
}));
}
// CORS Configuration
export function setupCORS(app: express.Application) {
app.use(cors({
origin: (origin, callback) => {
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
credentials: true,
maxAge: 86400, // 24 hours
}));
}
// Rate Limiting
export function setupRateLimiting(app: express.Application) {
// General rate limiter
const generalLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: 'Too many requests from this IP',
standardHeaders: true,
legacyHeaders: false,
});
// Authentication rate limiter (stricter)
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 5 attempts per window
skipSuccessfulRequests: true,
message: 'Too many authentication attempts',
});
app.use('/api/v1/auth', authLimiter);
app.use('/api/v1', generalLimiter);
}
// JWT Authentication Middleware
export interface JWTPayload {
sub: string;
iat: number;
exp: number;
scopes: string[];
}
export function authenticateJWT(req: express.Request, res: express.Response, next: express.NextFunction) {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.status(401).json({ error: 'Missing authorization header' });
}
const [scheme, token] = authHeader.split(' ');
if (scheme !== 'Bearer') {
return res.status(401).json({ error: 'Invalid authorization scheme' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload;
req.user = {
id: decoded.sub,
scopes: decoded.scopes,
};
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
}
// Scope-based Authorization Middleware
export function requireScope(requiredScope: string) {
return (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (!req.user) {
return res.status(401).json({ error: 'Authentication required' });
}
const userScopes = req.user.scopes || [];
// Check for admin scope (full access)
if (userScopes.includes('admin')) {
return next();
}
// Check for required scope
if (!userScopes.includes(requiredScope)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
// Role-based Authorization Middleware
export function requireRole(requiredRole: string) {
return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (!req.user) {
return res.status(401).json({ error: 'Authentication required' });
}
const user = await User.findById(req.user.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
if (user.role !== requiredRole && user.role !== 'admin') {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
// API Key Authentication Middleware
export async function authenticateAPIKey(req: express.Request, res: express.Response, next: express.NextFunction) {
const apiKey = req.headers['x-api-key'] as string;
if (!apiKey) {
return res.status(401).json({ error: 'Missing API key' });
}
try {
const key = await APIKey.findOne({ key: hashAPIKey(apiKey) }).populate('user');
if (!key || !key.active) {
return res.status(401).json({ error: 'Invalid API key' });
}
if (key.expiresAt && key.expiresAt < new Date()) {
return res.status(401).json({ error: 'API key expired' });
}
// Update last used
key.lastUsedAt = new Date();
await key.save();
req.user = {
id: key.user.id,
scopes: key.scopes,
};
req.apiKey = key.id;
next();
} catch (error) {
return res.status(500).json({ error: 'Authentication failed' });
}
}
// Input Validation Middleware
import { body, param, query, validationResult } from 'express-validator';
export function validateRequest(req: express.Request, res: express.Response, next: express.NextFunction) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
error: 'Validation failed',
details: errors.array(),
});
}
next();
}
// Validation rules
export const validationRules = {
createUser: [
body('email').isEmail().normalizeEmail(),
body('name').trim().isLength({ min: 1, max: 100 }),
body('password').isLength({ min: 8 }).matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/),
],
getUser: [
param('id').isMongoId(),
],
listUsers: [
query('page').optional().isInt({ min: 1 }),
query('per_page').optional().isInt({ min: 1, max: 100 }),
query('sort').optional().isIn(['created_at', 'name', 'email']),
query('order').optional().isIn(['asc', 'desc']),
],
createOrder: [
body('items').isArray({ min: 1 }),
body('items.*.productId').isMongoId(),
body('items.*.quantity').isInt({ min: 1 }),
body('shippingAddress').isObject(),
body('shippingAddress.street').trim().isLength({ min: 1 }),
body('shippingAddress.city').trim().isLength({ min: 1 }),
body('shippingAddress.postalCode').trim().isPostalCode('any'),
body('shippingAddress.country').trim().isLength({ min: 2, max: 2 }),
],
};
```
### 3. API Performance Optimization
**Performance Strategies:**
```yaml
# API Performance Optimization
caching_strategies:
http_caching:
description: "Leverage HTTP caching headers"
implementation:
cache_control:
- public: "Cacheable by any cache"
- private: "Cacheable by client only"
- no_cache: "Not cacheable"
- max_age: "Maximum freshness (seconds)"
- s_maxage: "Maximum freshness for shared caches"
- must_revalidate: "Must validate before use"
etag:
method: "Generate hash of response body"
header: "ETag: \"hash\""
validation: "If-None-Match header"
last_modified:
method: "Track resource modification time"
header: "Last-Modified: date"
validation: "If-Modified-Since header"
examples:
public_api:
max_age: 3600 # 1 hour
stale_while_revalidate: 86400 # 24 hours
user_specific:
max_age: 60 # 1 minute
must_revalidate: true
application_caching:
description: "Application-level caching"
implementation:
memory_cache:
tool: "Redis, Memcached"
ttl: "Configurable per resource type"
invalidation: "Manual or TTL-based"
distribution: "Redis Cluster, Memcached Cluster"
query_cache:
method: "Cache database query results"
key: "Hash of query parameters"
ttl: "5-15 minutes"
invalidation: "On data mutation"
object_cache:
method: "Cache hydrated objects"
key: "Resource ID"
ttl: "1-60 minutes"
invalidation: "On update/delete"
cdn_caching:
description: "Content Delivery Network caching"
implementation:
static_content:
- "Images, CSS, JavaScript"
- "Long TTL (1 year)"
- "Cache busting with versioning"
api_responses:
- "GET requests for public data"
- "Medium TTL (1-60 minutes)"
- "Cache invalidation on updates"
database_optimization:
query_optimization:
strategies:
- select_specific_fields: "Avoid SELECT *"
- use_indexes: "Create appropriate indexes"
- limit_results: "Use pagination"
- avoid_n_plus_1: "Use joins or data loader"
- use_connection_pooling: "Reuse connections"
- use_read_replicas: "Offload read queries"
connection_pooling:
configuration:
min_connections: 2
max_connections: 20
acquire_timeout: 30000 # 30 seconds
idle_timeout: 10000 # 10 seconds
database_indexing:
strategies:
- index_foreign_keys: "For joins"
- index_query_fields: "For filtering"
- index_sort_fields: "For sorting"
- composite_indexes: "For multi-field queries"
- partial_indexes: "For filtered queries"
read_replicas:
implementation:
primary: "Write operations"
replicas: "Read operations"
routing: "Automatic or manual"
consistency: "Eventual consistency"
response_optimization:
compression:
method: "Gzip, Brotli compression"
threshold: "Compress responses > 1KB"
exclude: "Images, videos (already compressed)"
field_selection:
description: "Allow clients to specify fields"
implementation:
graphql: "Built-in field selection"
rest: "fields query parameter"
grpc: "Field masks"
pagination:
strategies:
cursor_based:
method: "Cursor (opaque token)"
advantages: ["Efficient", "Consistent", "Supports real-time"]
disadvantages: ["No total count", "Cannot jump to page"]
offset_based:
method: "Offset and limit"
advantages: ["Simple", "Random access"]
disadvantages: ["Inefficient for large offsets", "Inconsistent with new data"]
data_formatting:
strategies:
- use_snake_case: "Consistent naming"
- iso_8601_dates: "Standard date format"
- camel_case_keys: "JavaScript convention"
- remove_nulls: "Omit null fields"
- use_enums: "Instead of strings"
```
**Performance Monitoring:**
```typescript
// API Performance Monitoring
import prometheus from 'prom-client';
// Metrics
const httpRequestDuration = new prometheus.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5],
});
const httpRequestsTotal = new prometheus.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
});
const httpResponseSize = new prometheus.Histogram({
name: 'http_response_size_bytes',
help: 'Size of HTTP responses in bytes',
labelNames: ['method', 'route', 'status_code'],
buckets: [100, 1000, 10000, 100000, 1000000],
});
const concurrentConnections = new prometheus.Gauge({
name: 'http_concurrent_connections',
help: 'Number of concurrent HTTP connections',
});
const databaseQueryDuration = new prometheus.Histogram({
name: 'database_query_duration_seconds',
help: 'Duration of database queries in seconds',
labelNames: ['operation', 'table'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1],
});
// Middleware to track metrics
export function metricsMiddleware() {
return (req: express.Request, res: express.Response, next: express.NextFunction) => {
const start = Date.now();
concurrentConnections.inc();
res.on('finish', () => {
const duration = (Date.now() - start) / 1000;
const route = req.route ? req.route.path : req.path;
const status = res.statusCode;
httpRequestDuration.labels(req.method, route, status).observe(duration);
httpRequestsTotal.labels(req.method, route, status).inc();
httpResponseSize.labels(req.method, route, status).observe(
parseInt(res.getHeader('Content-Length') as string || '0')
);
concurrentConnections.dec();
});
next();
};
}
// Database query tracking
export function trackDatabaseQuery(operation: string, table: string) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const start = Date.now();
try {
const result = await originalMethod.apply(this, args);
const duration = (Date.now() - start) / 1000;
databaseQueryDuration.labels(operation, table).observe(duration);
return result;
} catch (error) {
const duration = (Date.now() - start) / 1000;
databaseQueryDuration.labels(`${operation}_error`, table).observe(duration);
throw error;
}
};
return descriptor;
};
}
// Expose metrics endpoint
export function setupMetricsEndpoint(app: express.Application) {
app.get('/metrics', async (req: express.Request, res: express.Response) => {
res.set('Content-Type', prometheus.register.contentType);
res.end(await prometheus.register.metrics());
});
}
```
### 4. API Documentation
**OpenAPI Specification:**
```yaml
# OpenAPI 3.0 Specification
openapi: 3.0.3
info:
title: Example API
description: |
Comprehensive API documentation for the Example API.
## Authentication
This API uses OAuth 2.0 for authentication. Include your access token in the `Authorization` header:
```
Authorization: Bearer YOUR_ACCESS_TOKEN
```
## Rate Limiting
Rate limits are applied per API key. The default limit is 100 requests per 15 minutes.
## Pagination
List endpoints support pagination using `page` and `per_page` parameters.
version: 1.0.0
contact:
name: API Support
email: support@example.com
url: https://example.com/support
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging-api.example.com/v1
description: Staging server
- url: http://localhost:3000/v1
description: Local development server
security:
- OAuth2: []
- ApiKeyAuth: []
tags:
- name: Users
description: User management operations
- name: Orders
description: Order management operations
- name: Products
description: Product catalog operations
- name: Authentication
description: Authentication operations
paths:
/users:
get:
operationId: listUsers
summary: List users
description: Retrieve a paginated list of users
tags:
- Users
parameters:
- name: page
in: query
description: Page number
required: false
schema:
type: integer
minimum: 1
default: 1
- name: per_page
in: query
description: Items per page
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: sort
in: query
description: Sort field
required: false
schema:
type: string
enum: [created_at, name, email]
default: created_at
- name: order
in: query
description: Sort order
required: false
schema:
type: string
enum: [asc, desc]
default: desc
- name: status
in: query
description: Filter by status
required: false
schema:
type: string
enum: [active, inactive, suspended, pending]
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
examples:
success:
summary: Successful response
value:
data:
- id: "user123"
email: "john@example.com"
name: "John Doe"
status: "active"
created_at: "2024-01-15T10:30:00Z"
updated_at: "2024-01-15T10:30:00Z"
pagination:
page: 1
per_page: 20
total_pages: 50
total_count: 1000
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/TooManyRequests'
post:
operationId: createUser
summary: Create user
description: Create a new user
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
examples:
john_doe:
summary: John Doe
value:
email: "john@example.com"
name: "John Doe"
password: "SecurePassword123!"
profile:
first_name: "John"
last_name: "Doe"
responses:
'201':
description: User created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'409':
description: Conflict (email already exists)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Email already exists"
/users/{userId}:
get:
operationId: getUser
summary: Get user
description: Retrieve a specific user by ID
tags:
- Users
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
'401':
$ref: '#/components/responses/Unauthorized'
patch:
operationId: updateUser
summary: Update user
description: Update specific fields of a user
tags:
- Users
parameters:
- $ref: '#/components/parameters/UserId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: User updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'401':
$ref: '#/components/responses/Unauthorized'
delete:
operationId: deleteUser
summary: Delete user
description: Delete a user
tags:
- Users
parameters:
- $ref: '#/components/parameters/UserId'
responses:
'204':
description: User deleted successfully
'404':
$ref: '#/components/responses/NotFound'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes:
read:users: Read user information
write:users: Create, update, delete users
read:orders: Read order information
write:orders: Create, update, cancel orders
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API key authentication
parameters:
UserId:
name: userId
in: path
description: User ID
required: true
schema:
type: string
format: uuid
example: "user123"
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
description: User ID
email:
type: string
format: email
description: User email
name:
type: string
description: User full name
status:
type: string
enum: [active, inactive, suspended, pending]
description: User account status
created_at:
type: string
format: date-time
description: Account creation timestamp
updated_at:
type: string
format: date-time
description: Last update timestamp
profile:
$ref: '#/components/schemas/UserProfile'
required:
- id
- email
- name
- status
- created_at
- updated_at
UserProfile:
type: object
properties:
first_name:
type: string
last_name:
type: string
phone:
type: string
address:
$ref: '#/components/schemas/Address'
Address:
type: object
properties:
street:
type: string
city:
type: string
state:
type: string
postal_code:
type: string
country:
type: string
format: ISO 3166-1 alpha-2
required:
- street
- city
- state
- postal_code
- country
CreateUserRequest:
type: object
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
password:
type: string
minLength: 8
description: "Must contain at least one uppercase letter, one lowercase letter, and one number"
profile:
$ref: '#/components/schemas/UserProfile'
required:
- email
- name
- password
UpdateUserRequest:
type: object
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive, suspended, pending]
profile:
$ref: '#/components/schemas/UserProfile'
UserResponse:
type: object
properties:
data:
$ref: '#/components/schemas/User'
required:
- data
UserListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
required:
- data
- pagination
Pagination:
type: object
properties:
page:
type: integer
minimum: 1
description: Current page number
per_page:
type: integer
minimum: 1
maximum: 100
description: Items per page
total_pages:
type: integer
minimum: 1
description: Total number of pages
total_count:
type: integer
minimum: 0
description: Total number of items
required:
- page
- per_page
- total_pages
- total_count
ErrorResponse:
type: object
properties:
error:
type: string
description: Error message
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
required:
- error
responses:
BadRequest:
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Validation failed"
details:
- field: "email"
message: "Invalid email format"
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Authentication required"
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "User not found"
TooManyRequests:
description: Too many requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Rate limit exceeded"
headers:
X-RateLimit-Limit:
schema:
type: integer
description: Request limit per time window
X-RateLimit-Remaining:
schema:
type: integer
description: Remaining requests in current window
X-RateLimit-Reset:
schema:
type: integer
description: Time when the rate limit resets (Unix timestamp)
```
### 5. SDK Client Development
**TypeScript SDK Example:**
```typescript
// API SDK Client Implementation
import axios, { AxiosInstance, AxiosRequestConfig, AxiosError } from 'axios';
// Configuration
export interface APIConfig {
baseURL: string;
apiKey?: string;
accessToken?: string;
timeout?: number;
retryAttempts?: number;
retryDelay?: number;
}
// Error types
export class APIError extends Error {
constructor(
public message: string,
public statusCode: number,
public details?: any
) {
super(message);
this.name = 'APIError';
}
}
export class ValidationError extends APIError {
constructor(
public fieldErrors: Record<string, string[]>
) {
super('Validation failed', 400, fieldErrors);
this.name = 'ValidationError';
}
}
export class AuthenticationError extends APIError {
constructor() {
super('Authentication failed', 401);
this.name = 'AuthenticationError';
}
}
export class RateLimitError extends APIError {
constructor(
public retryAfter?: number,
public limit?: number,
public remaining?: number
) {
super('Rate limit exceeded', 429);
this.name = 'RateLimitError';
}
}
// Main client
export class APIClient {
private axiosInstance: AxiosInstance;
private config: APIConfig;
constructor(config: APIConfig) {
this.config = {
timeout: 30000,
retryAttempts: 3,
retryDelay: 1000,
...config,
};
this.axiosInstance = axios.create({
baseURL: this.config.baseURL,
timeout: this.config.timeout,
});
this.setupInterceptors();
}
private setupInterceptors() {
// Request interceptor
this.axiosInstance.interceptors.request.use(
(config) => {
if (this.config.apiKey) {
config.headers['X-API-Key'] = this.config.apiKey;
}
if (this.config.accessToken) {
config.headers['Authorization'] = `Bearer ${this.config.accessToken}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor
this.axiosInstance.interceptors.response.use(
(response) => response.data,
async (error: AxiosError) => {
const config = error.config as any & { _retry?: number };
// Retry on 5xx errors
if (
error.response?.status &&
error.response.status >= 500 &&
error.response.status < 600 &&
(!config._retry || config._retry < this.config.retryAttempts!)
) {
config._retry = config._retry || 0;
config._retry++;
await this.delay(this.config.retryDelay! * config._retry);
return this.axiosInstance(config);
}
// Handle specific errors
if (error.response?.status === 401) {
throw new AuthenticationError();
}
if (error.response?.status === 429) {
const retryAfter = parseInt(error.response.headers['retry-after'] || '0');
const limit = parseInt(error.response.headers['x-ratelimit-limit'] || '0');
const remaining = parseInt(error.response.headers['x-ratelimit-remaining'] || '0');
throw new RateLimitError(retryAfter, limit, remaining);
}
if (error.response?.status === 400) {
throw new ValidationError(error.response.data.details);
}
throw new APIError(
error.response?.data?.error || error.message,
error.response?.status || 500,
error.response?.data
);
}
);
}
private delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// HTTP methods
private async request<T>(
config: AxiosRequestConfig
): Promise<T> {
return this.axiosInstance.request<T>(config);
}
async get<T>(
url: string,
params?: Record<string, any>,
config?: AxiosRequestConfig
): Promise<T> {
return this.request<T>({
method: 'GET',
url,
params,
...config,
});
}
async post<T>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T> {
return this.request<T>({
method: 'POST',
url,
data,
...config,
});
}
async put<T>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T> {
return this.request<T>({
method: 'PUT',
url,
data,
...config,
});
}
async patch<T>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T> {
return this.request<T>({
method: 'PATCH',
url,
data,
...config,
});
}
async delete<T>(
url: string,
config?: AxiosRequestConfig
): Promise<T> {
return this.request<T>({
method: 'DELETE',
url,
...config,
});
}
}
// Resource clients
export class UsersClient {
constructor(private apiClient: APIClient) {}
async list(params?: ListUsersParams): Promise<UserListResponse> {
return this.apiClient.get<UserListResponse>('/users', params);
}
async get(userId: string): Promise<UserResponse> {
return this.apiClient.get<UserResponse>(`/users/${userId}`);
}
async create(data: CreateUserRequest): Promise<UserResponse> {
return this.apiClient.post<UserResponse>('/users', data);
}
async update(userId: string, data: UpdateUserRequest): Promise<UserResponse> {
return this.apiClient.patch<UserResponse>(`/users/${userId}`, data);
}
async delete(userId: string): Promise<void> {
return this.apiClient.delete<void>(`/users/${userId}`);
}
}
export class OrdersClient {
constructor(private apiClient: APIClient) {}
async list(params?: ListOrdersParams): Promise<OrderListResponse> {
return this.apiClient.get<OrderListResponse>('/orders', params);
}
async get(orderId: string): Promise<OrderResponse> {
return this.apiClient.get<OrderResponse>(`/orders/${orderId}`);
}
async create(data: CreateOrderRequest): Promise<OrderResponse> {
return this.apiClient.post<OrderResponse>('/orders', data);
}
async cancel(orderId: string, reason?: string): Promise<OrderResponse> {
return this.apiClient.post<OrderResponse>(`/orders/${orderId}/cancel`, { reason });
}
}
// Types
export interface User {
id: string;
email: string;
name: string;
status: 'active' | 'inactive' | 'suspended' | 'pending';
created_at: string;
updated_at: string;
profile?: UserProfile;
}
export interface UserResponse {
data: User;
}
export interface UserListResponse {
data: User[];
pagination: {
page: number;
per_page: number;
total_pages: number;
total_count: number;
};
}
export interface CreateUserRequest {
email: string;
name: string;
password: string;
profile?: {
first_name?: string;
last_name?: string;
phone?: string;
};
}
export interface UpdateUserRequest {
email?: string;
name?: string;
status?: 'active' | 'inactive' | 'suspended' | 'pending';
profile?: CreateUserRequest['profile'];
}
export interface ListUsersParams {
page?: number;
per_page?: number;
sort?: 'created_at' | 'name' | 'email';
order?: 'asc' | 'desc';
status?: 'active' | 'inactive' | 'suspended' | 'pending';
}
export interface Order {
id: string;
user_id: string;
items: OrderItem[];
total: number;
status: OrderStatus;
created_at: string;
updated_at: string;
}
export interface OrderItem {
id: string;
product_id: string;
quantity: number;
price: number;
subtotal: number;
}
export type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
export interface OrderResponse {
data: Order;
}
export interface OrderListResponse {
data: Order[];
pagination: {
page: number;
per_page: number;
total_pages: number;
total_count: number;
};
}
export interface CreateOrderRequest {
items: {
product_id: string;
quantity: number;
}[];
shipping_address: {
street: string;
city: string;
state: string;
postal_code: string;
country: string;
};
billing_address?: CreateOrderRequest['shipping_address'];
}
export interface ListOrdersParams {
page?: number;
per_page?: number;
status?: OrderStatus;
}
// Factory function
export function createAPIClient(config: APIConfig) {
const apiClient = new APIClient(config);
return {
users: new UsersClient(apiClient),
orders: new OrdersClient(apiClient),
};
}
// Usage example
const api = createAPIClient({
baseURL: 'https://api.example.com/v1',
apiKey: process.env.API_KEY,
});
async function main() {
try {
// List users
const users = await api.users.list({
page: 1,
per_page: 20,
status: 'active',
});
console.log(`Found ${users.pagination.total_count} users`);
// Create user
const user = await api.users.create({
email: 'john@example.com',
name: 'John Doe',
password: 'SecurePassword123!',
});
console.log(`Created user: ${user.data.id}`);
// Create order
const order = await api.orders.create({
items: [
{
product_id: 'product123',
quantity: 2,
},
],
shipping_address: {
street: '123 Main St',
city: 'San Francisco',
state: 'CA',
postal_code: '94102',
country: 'US',
},
});
console.log(`Created order: ${order.data.id}`);
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.fieldErrors);
} else if (error instanceof AuthenticationError) {
console.error('Authentication failed');
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded');
} else {
console.error('Error:', error);
}
}
}
```
---
## Conclusion
The API Architect Agent provides comprehensive API design and implementation capabilities across REST, GraphQL, and gRPC. By following this specification, the agent delivers:
1. **API Design**: Resource-oriented, uniform interface, RESTful principles
2. **Security**: Authentication, authorization, rate limiting, input validation
3. **Performance**: Caching, optimization, monitoring strategies
4. **Documentation**: OpenAPI specifications, comprehensive guides
5. **SDK Development**: Type-safe client libraries in multiple languages
6. **Testing**: Contract testing, integration testing, performance testing
7. **API Gateway**: Configuration for routing, transformation, and security
This agent specification ensures production-ready APIs that are secure, performant, and developer-friendly across all use cases and requirements.