OpenWriterControle/.opencode/context/development/api-design.md
Darren Hinde c8f7103cb6
refactor(evals): consolidate documentation and enhance test infrastructure (#56)
* feat(agents): implement category-based agent organization system

- Organize agents into domain categories (core, development, content, data, product, learning)
- Move 10 agents to category subdirectories with proper git rename tracking
- Update 13 subagents with category and type metadata in frontmatter
- Add category metadata files (0-category.json) documenting common patterns
- Implement local registry fallback in install script for offline development
- Add comprehensive validation suite with 15 automated tests (100% pass rate)
- Enhance registry validation with duplicate ID and consistency checks
- Update eval framework with intelligent path resolution (backward compatible)
- Archive legacy eval structure to _archive/ for reference
- Update all documentation to reflect category-based structure
- Bump version to 0.5.0 with accurate CHANGELOG

Technical Details:
- 23 agents organized (10 category agents, 13 subagents)
- 6 category directories created
- Path resolution supports both agent IDs and category paths
- Registry schema updated to v2.0.0
- 159 files changed, 872 insertions(+), 10738 deletions(-)

BREAKING CHANGE: Agent file paths now use category structure. Update references from .opencode/agent/openagent.md to .opencode/agent/core/openagent.md. Eval framework maintains backward compatibility via path resolution.

* refactor(evals): consolidate documentation and enhance test infrastructure

- Remove temporary project tracking files (PHASE_5_COMPLETE, PROJECT_COMPLETE, etc.)
- Consolidate evaluation framework docs into main README
- Enhance test execution with improved logging and multi-prompt support
- Move system-builder from core to meta category
- Add comprehensive test suites for openagent with organized structure
- Create evaluation test structure for all subagents
- Clean up archived workflows and redundant documentation
- Update registry to reflect new agent organization
- Add shared test templates and golden test patterns

* feat(ci): add manual trigger support for bot-created PRs in validate-registry workflow

- Add pr_number input to workflow_dispatch for manually triggering validation
- Fetch PR details dynamically when triggered manually
- Support both automatic (PR event) and manual (workflow_dispatch) triggers
- Enable validation of bot-created PRs like automated version bumps
- Update branch detection and push logic to handle both trigger types
- Add documentation explaining how to manually trigger for bot PRs

* feat(evals): add explicit context file validation to test framework

- Add expectedContextFiles field to test YAML schema for explicit context file specification
- Enhance context-loading-evaluator to support both auto-detect and explicit validation modes
- Update documentation with comprehensive guide and examples
- Clean up archived legacy test structure (90+ old test files)
- Add new example tests demonstrating explicit context validation
- Backward compatible with existing tests

* feat(evals): add multi-agent logging system and performance optimizations

Implement comprehensive multi-agent logging and performance improvements for the eval framework.

Task 01: Multi-Agent Logging System
- Add complete hierarchical logging module (evals/framework/src/logging/)
  - SessionTracker: tracks parent-child delegation hierarchies
  - MultiAgentLogger: pretty-prints logs with visual indentation
  - Formatters: box characters and emoji formatting
  - 37 passing unit tests (session-tracker, logger, integration)
- Integrate with SDK event stream handler
  - Hook into session.created, message.updated, message.part.updated events
  - Real-time child session detection via timestamp heuristics
  - Message deduplication for cleaner output
- Enable in debug mode only (<1% performance overhead)
- Add demo script and comprehensive documentation

Task 02: Performance Optimizations
- Reduce grace period from 5s to 2s (67% reduction, 10-20% faster tests)
- Add PerformanceMetricsEvaluator for bottleneck identification
  - Collects tool latencies, inference time, idle time
  - Provides full performance visibility
- Update smoke test to validate delegation (core feature)
  - Replace simple read test with multi-agent delegation test
  - Tests both parent and child agent functionality
  - Validates multi-agent logging system

Results:
- 37 unit tests passing
- Smoke test passing (95/100 score)
- Clean hierarchical logging output
- 10-20% faster test execution
- Full multi-agent visibility

Files changed: 16 files, +2678 lines
Time saved: ~6-8 days (completed in 6 hours vs 3-5 day estimate)

* feat(evals): show child agent execution in non-debug mode

- Enable MultiAgentLogger in both debug and non-debug modes
- Add verbose parameter to control output level
- Non-verbose mode shows concise child session lifecycle:
  - Child agent started message
  - Child agent completed with duration
- Verbose mode (--debug) shows full delegation hierarchy
- Update documentation to reflect new behavior

This provides visibility into delegation without overwhelming output,
giving confidence that child agents are actually running.

* feat(evals): improve delegation testing and behavior validation

Major improvements to eval framework:

Test Suite:
- Add 00-smoke-test.yaml (basic read operation)
- Rename 01-smoke-test.yaml → 02-delegation-test.yaml (delegation test)
- Add simple-responder test agent for delegation testing
- Add debug test: simple-subagent-call.yaml

Evaluators:
- Add agent-model-evaluator.ts for agent/model validation
- Enhance behavior-evaluator.ts with detailed task tool output
- Improve delegation-evaluator.ts with better evidence tracking

Schema & Execution:
- Add expectedAgent and expectedModel to test schema
- Improve test executor with better logging and error handling

Documentation:
- Update evals/README.md with new features and performance improvements
- Remove outdated MULTI_AGENT_LOGGING_COMPLETE.md

Registry:
- Add simple-responder test agent to registry

Fixes:
- Fix dashboard.sh path resolution

These changes provide better visibility into delegation, improved test
coverage, and clearer validation of agent behavior.

* chore: add GitHub Actions workflow and plugin documentation

- Add .github/workflows/evals/run-evaluations.yml for automated eval testing
- Add dev/ai-tools/opencode/plugins/Plugin-inspiration.md for plugin development reference
2025-12-18 09:52:11 +00:00

384 lines
8 KiB
Markdown

# API Design Patterns
**Category**: development
**Purpose**: REST API design principles, GraphQL patterns, and API versioning strategies
**Used by**: backend-specialist
---
## Overview
This guide covers best practices for designing robust, scalable, and maintainable APIs, including REST, GraphQL, and versioning strategies.
## REST API Design
### 1. Resource-Based URLs
**Use nouns, not verbs**:
```
# Bad
GET /getUsers
POST /createUser
POST /updateUser/123
# Good
GET /users
POST /users
PUT /users/123
PATCH /users/123
DELETE /users/123
```
### 2. HTTP Methods
**Use appropriate HTTP methods**:
- `GET` - Retrieve resources (idempotent, safe)
- `POST` - Create new resources
- `PUT` - Replace entire resource (idempotent)
- `PATCH` - Partial update (idempotent)
- `DELETE` - Remove resource (idempotent)
### 3. Status Codes
**Use standard HTTP status codes**:
```
2xx Success
200 OK - Successful GET, PUT, PATCH
201 Created - Successful POST
204 No Content - Successful DELETE
4xx Client Errors
400 Bad Request - Invalid input
401 Unauthorized - Missing/invalid auth
403 Forbidden - Authenticated but not authorized
404 Not Found - Resource doesn't exist
409 Conflict - Resource conflict (e.g., duplicate)
422 Unprocessable Entity - Validation errors
5xx Server Errors
500 Internal Server Error - Unexpected error
503 Service Unavailable - Temporary unavailability
```
### 4. Consistent Response Format
**Standardize response structure**:
```json
// Success response
{
"data": {
"id": "123",
"name": "John Doe",
"email": "john@example.com"
},
"meta": {
"timestamp": "2024-01-01T00:00:00Z"
}
}
// Error response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
},
"meta": {
"timestamp": "2024-01-01T00:00:00Z",
"requestId": "abc-123"
}
}
// Collection response
{
"data": [...],
"meta": {
"total": 100,
"page": 1,
"pageSize": 20,
"totalPages": 5
},
"links": {
"self": "/users?page=1",
"next": "/users?page=2",
"prev": null,
"first": "/users?page=1",
"last": "/users?page=5"
}
}
```
### 5. Filtering, Sorting, Pagination
**Support common query operations**:
```
# Filtering
GET /users?status=active&role=admin
# Sorting
GET /users?sort=createdAt:desc,name:asc
# Pagination
GET /users?page=2&pageSize=20
# Field selection
GET /users?fields=id,name,email
# Search
GET /users?q=john
```
### 6. Nested Resources
**Handle relationships appropriately**:
```
# Good - Shallow nesting
GET /users/123/posts
GET /posts?userId=123
# Avoid - Deep nesting
GET /users/123/posts/456/comments/789
# Better
GET /comments/789
```
## GraphQL Patterns
### 1. Schema Design
**Design clear, intuitive schemas**:
```graphql
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
publishedAt: DateTime
}
type Query {
user(id: ID!): User
users(filter: UserFilter, page: Int, pageSize: Int): UserConnection!
post(id: ID!): Post
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
input CreateUserInput {
name: String!
email: String!
}
input UserFilter {
status: UserStatus
role: UserRole
search: String
}
```
### 2. Resolver Patterns
**Implement efficient resolvers**:
```javascript
const resolvers = {
Query: {
user: async (_, { id }, { dataSources }) => {
return dataSources.userAPI.getUser(id);
},
users: async (_, { filter, page, pageSize }, { dataSources }) => {
return dataSources.userAPI.getUsers({ filter, page, pageSize });
}
},
User: {
posts: async (user, _, { dataSources }) => {
// Use DataLoader to batch requests
return dataSources.postAPI.getPostsByUserId(user.id);
}
},
Mutation: {
createUser: async (_, { input }, { dataSources, user }) => {
// Check authorization
if (!user) throw new AuthenticationError('Not authenticated');
// Validate input
const validatedInput = validateUserInput(input);
// Create user
return dataSources.userAPI.createUser(validatedInput);
}
}
};
```
### 3. DataLoader for N+1 Prevention
**Batch and cache database queries**:
```javascript
import DataLoader from 'dataloader';
const userLoader = new DataLoader(async (userIds) => {
const users = await db.users.findMany({
where: { id: { in: userIds } }
});
// Return in same order as input
return userIds.map(id => users.find(u => u.id === id));
});
// Usage in resolver
const user = await userLoader.load(userId);
```
## API Versioning
### 1. URL Versioning
**Version in the URL path**:
```
GET /v1/users
GET /v2/users
```
**Pros**: Clear, easy to route
**Cons**: URL changes, harder to maintain multiple versions
### 2. Header Versioning
**Version in Accept header**:
```
GET /users
Accept: application/vnd.myapi.v2+json
```
**Pros**: Clean URLs, flexible
**Cons**: Less visible, harder to test
### 3. Deprecation Strategy
**Communicate deprecation clearly**:
```javascript
// Response headers
Deprecation: true
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Link: <https://api.example.com/v2/users>; rel="successor-version"
// Response body
{
"data": {...},
"meta": {
"deprecated": true,
"deprecationDate": "2024-12-31",
"migrationGuide": "https://docs.example.com/migration/v1-to-v2"
}
}
```
## Authentication & Authorization
### 1. JWT Tokens
**Use JWT for stateless auth**:
```javascript
// Token structure
{
"sub": "user-123",
"email": "user@example.com",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
// Middleware
function authenticateToken(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;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
}
```
### 2. Role-Based Access Control
**Implement RBAC**:
```javascript
function authorize(...roles) {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({ error: 'Not authenticated' });
}
if (!roles.includes(req.user.role)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
// Usage
app.delete('/users/:id',
authenticateToken,
authorize('admin'),
deleteUser
);
```
## Best Practices
1. **Use HTTPS everywhere** - Encrypt all API traffic
2. **Implement rate limiting** - Prevent abuse and ensure fair usage
3. **Validate all inputs** - Never trust client data
4. **Use proper error handling** - Return meaningful error messages
5. **Document your API** - Use OpenAPI/Swagger or GraphQL introspection
6. **Version your API** - Plan for breaking changes
7. **Implement CORS properly** - Configure allowed origins carefully
8. **Log requests and errors** - Enable debugging and monitoring
9. **Use caching** - Implement ETags, Cache-Control headers
10. **Test thoroughly** - Unit, integration, and contract tests
## Anti-Patterns
- ❌ **Exposing internal IDs** - Use UUIDs or opaque identifiers
- ❌ **Returning too much data** - Support field selection
- ❌ **Ignoring idempotency** - PUT/PATCH/DELETE should be idempotent
- ❌ **Inconsistent naming** - Use camelCase or snake_case consistently
- ❌ **Missing pagination** - Always paginate collections
- ❌ **No rate limiting** - Protect against abuse
- ❌ **Verbose error messages** - Don't leak implementation details
- ❌ **Synchronous long operations** - Use async jobs for long tasks
## References
- REST API Design Rulebook by Mark Masse
- GraphQL Best Practices (graphql.org)
- API Design Patterns by JJ Geewax
- OpenAPI Specification (swagger.io)