API-Design-Experte System-Prompt
Von Wikiprompt, der freien Prompt-Enzyklopädie
API-Design-Experte System-Prompt Ein umfassender System-Prompt für einen API-Design-Experten, der REST, GraphQL, gRPC und Echtzeit-APIs abdeckt, mit aufgabenbasierter Ausführung und Qualitäts-Checklisten.
Prompt-InhaltSpeichern
🌐
# API Design Expert - Task Output
## Context
- **API Purpose**: Design a scalable, secure, and developer-friendly API for a hypothetical e-commerce platform ("ShopSphere") that manages products, orders, customers, and inventory.
- **Target Consumers**: Mobile apps (iOS/Android), third-party integrators, internal admin dashboard, and partner logistics systems.
- **Use Cases**:
- Browse/search products with filtering and pagination
- Create and manage customer accounts and authentication
- Place, track, and cancel orders
- Real-time inventory updates and stock alerts
- Webhook notifications for order status changes
- **Chosen Architecture Pattern**: REST with OpenAPI 3.0 specification. Justification: Broad compatibility, stateless scalability, mature tooling, and simplicity for third-party adoption. GraphQL considered but rejected for initial version due to complexity and caching challenges.
- **Security Requirements**: OAuth 2.0 with JWT for user auth, API keys for partner access, mTLS for internal services, rate limiting, CORS restrictions.
- **Performance Requirements**: P95 latency < 300ms for read endpoints, < 500ms for writes, 99.9% uptime SLA, support 10K concurrent users.
- **Compliance**: GDPR for EU customers, PCI-DSS for payment processing, SOC2 for data handling.
---
## API Design Plan
### Task Checklist
- [ ] **API-PLAN-1.1 [Resource Model]**:
- **Resources**: `customers`, `products`, `orders`, `order-items`, `inventory`, `categories`, `reviews`, `shipments`
- **Relationships**: Customer has many Orders; Order has many OrderItems; Product belongs to Category; Product has one Inventory; Order has one Shipment
- **URI Structure**: Base path `/v1`, resources as plural nouns, nested for sub-resources (e.g., `/v1/customers/{customerId}/orders`)
- **Versioning**: URI versioning (`/v1/`) for simplicity and explicit client control
- **Authentication**: OAuth 2.0 Bearer tokens for user endpoints; API keys for partner endpoints; scopes per resource
- [ ] **API-PLAN-1.2 [Endpoint Inventory]**:
- **Public Endpoints**: `POST /v1/auth/login`, `POST /v1/customers`, `GET /v1/products`, `GET /v1/products/{id}`, `POST /v1/orders`, `GET /v1/orders/{id}`, `PATCH /v1/orders/{id}`
- **Partner Endpoints**: `GET /v1/inventory`, `PATCH /v1/inventory/{productId}`, `POST /v1/webhooks`
- **Admin Endpoints**: `GET /v1/customers`, `DELETE /v1/products/{id}`, `GET /v1/reports/sales`
- **Pagination**: Cursor-based for public endpoints, offset-based for admin endpoints
- **Filtering**: Query params (`?category=electronics&price_min=100&price_max=500`)
- **Sorting**: `?sort=-created_at` for descending, `?sort=name` for ascending
- [ ] **API-PLAN-1.3 [Error Handling]**:
- **Standard Format**: `{ "error": { "code": "VALIDATION_ERROR", "message": "Field 'email' is invalid", "details": [...], "correlation_id": "abc-123" } }`
- **Status Codes**: 400 (validation), 401 (unauth), 403 (forbidden), 404 (not found), 409 (conflict), 422 (unprocessable), 429 (rate limit), 500 (internal), 503 (unavailable)
- **Correlation IDs**: Generated per request, returned in response headers and error bodies
- **Retry-After**: Included for 429 responses with rate limit reset time
- [ ] **API-PLAN-1.4 [Security]**:
- **OAuth 2.0 Flows**: Authorization Code + PKCE for mobile/web, Client Credentials for partner services
- **JWT Claims**: `sub` (user ID), `scope` (e.g., `read:products`, `write:orders`), `exp`, `iat`, `iss`
- **API Keys**: For partner access, sent via `X-API-Key` header, hashed at rest
- **Rate Limiting**: Per-user: 100 req/min; per-API-key: 1000 req/min; per-IP: 500 req/min
- **CORS**: Allow `https://app.shopsphere.com`, `https://admin.shopsphere.com`; methods GET, POST, PATCH, DELETE; headers Authorization, Content-Type, X-API-Key
- [ ] **API-PLAN-1.5 [Caching and Performance]**:
- **ETags**: Generated from response body hash, used for conditional GET requests
- **Cache-Control**: `public, max-age=300` for product listings; `private, no-store` for customer data
- **Compression**: gzip and brotli supported via `Accept-Encoding`
- **Field Selection**: `?fields=id,name,price` to reduce payload size
- **Idempotency**: `Idempotency-Key` header required for POST /orders, stored for 24 hours
---
## API Design Items
### Task Checklist
- [ ] **API-ITEM-1.1 [Authentication - Login]**:
- **Method**: POST
- **Path**: `/v1/auth/login`
- **Request Schema**: `{ "email": "string (email format)", "password": "string (min 8 chars)" }`
- **Response Schema**: 200 OK - `{ "access_token": "string", "refresh_token": "string", "expires_in": 3600, "token_type": "Bearer" }`
- **Errors**: 401 (invalid credentials), 429 (rate limited), 400 (validation)
- [ ] **API-ITEM-1.2 [Customer Registration]**:
- **Method**: POST
- **Path**: `/v1/customers`
- **Request Schema**: `{ "firstName": "string (required)", "lastName": "string (required)", "email": "string (required, unique)", "password": "string (min 8, max 64)", "address": { "street": "string", "city": "string", "postalCode": "string", "country": "string (ISO 3166-1 alpha-2)" } }`
- **Response Schema**: 201 Created - `{ "id": "string (UUID)", "firstName": "string", "lastName": "string", "email": "string", "address": { ... }, "createdAt": "string (ISO 8601)" }`
- **Errors**: 409 (email exists), 422 (validation), 400 (malformed)
- [ ] **API-ITEM-1.3 [Product Listing]**:
- **Method**: GET
- **Path**: `/v1/products`
- **Query Params**: `category` (string), `price_min` (number), `price_max` (number), `sort` (string: `name`, `-price`, `created_at`), `cursor` (string), `limit` (int, default 20, max 100), `fields` (comma-separated)
- **Response Schema**: 200 OK - `{ "data": [ { "id": "string", "name": "string", "description": "string", "price": "number (2 decimals)", "currency": "string (ISO 4217)", "category": { "id": "string", "name": "string" }, "inStock": "boolean", "imageUrls": ["string"] } ], "pagination": { "nextCursor": "string|null", "hasMore": "boolean" } }`
- **Errors**: 400 (invalid filter), 401 (unauthorized)
- [ ] **API-ITEM-1.4 [Product Detail]**:
- **Method**: GET
- **Path**: `/v1/products/{productId}`
- **Path Params**: `productId` (UUID format)
- **Response Schema**: 200 OK - `{ "id": "string", "name": "string", "description": "string", "price": "number", "currency": "string", "category": { ... }, "inventory": { "quantity": "int", "reserved": "int" }, "reviews": { "averageRating": "number", "count": "int" }, "createdAt": "string", "updatedAt": "string" }`
- **Errors**: 404 (not found), 400 (invalid ID format)
- [ ] **API-ITEM-1.5 [Order Creation]**:
- **Method**: POST
- **Path**: `/v1/orders`
- **Headers**: `Idempotency-Key` (required, UUID format)
- **Request Schema**: `{ "customerId": "string (required)", "items": [ { "productId": "string (required)", "quantity": "int (min 1, max 100)" } ], "shippingAddress": { "street": "string", "city": "string", "postalCode": "string", "country": "string" }, "paymentMethod": "string (enum: card, paypal, apple_pay)" }`
- **Response Schema**: 201 Created - `{ "id": "string", "status": "string (enum: pending, confirmed, shipped, delivered, cancelled)", "items": [ { "productId": "string", "quantity": "int", "unitPrice": "number", "lineTotal": "number" } ], "totalAmount": "number", "currency": "string", "createdAt": "string", "links": { "self": "/v1/orders/{id}", "cancel": "/v1/orders/{id}" } }`
- **Errors**: 409 (duplicate idempotency key), 422 (insufficient stock), 400 (validation)
- [ ] **API-ITEM-1.6 [Order Retrieval]**:
- **Method**: GET
- **Path**: `/v1/orders/{orderId}`
- **Response Schema**: 200 OK - `{ "id": "string", "status": "string", "items": [...], "totalAmount": "number", "shippingAddress": { ... }, "trackingNumber": "string|null", "estimatedDelivery": "string|null", "createdAt": "string", "updatedAt": "string", "links": { "self": "...", "shipment": "/v1/shipments/{id}" } }`
- **Errors**: 404 (not found), 403 (access denied)
- [ ] **API-ITEM-1.7 [Order Cancellation]**:
- **Method**: PATCH
- **Path**: `/v1/orders/{orderId}`
- **Request Schema**: `{ "status": "string (enum: cancelled)", "reason": "string (optional, max 200 chars)" }`
- **Response Schema**: 200 OK - `{ "id": "string", "status": "cancelled", "cancelledAt": "string", "refundStatus": "string (enum: pending, processed)" }`
- **Errors**: 409 (order already shipped), 404 (not found), 422 (invalid transition)
- [ ] **API-ITEM-1.8 [Inventory Update]**:
- **Method**: PATCH
- **Path**: `/v1/inventory/{productId}`
- **Auth**: API Key (scope: `write:inventory`)
- **Request Schema**: `{ "quantity": "int (required, >= 0)", "operation": "string (enum: set, increment, decrement)" }`
- **Response Schema**: 200 OK - `{ "productId": "string", "quantity": "int", "updatedAt": "string" }`
- **Errors**: 404 (product not found), 422 (negative result), 401 (invalid key)
- [ ] **API-ITEM-1.9 [Webhook Registration]**:
- **Method**: POST
- **Path**: `/v1/webhooks`
- **Auth**: API Key (scope: `write:webhooks`)
- **Request Schema**: `{ "url": "string (https only)", "events": ["string (enum: order.created, order.shipped, inventory.low)"], "secret": "string (min 16 chars)" }`
- **Response Schema**: 201 Created - `{ "id": "string", "url": "string", "events": [...], "createdAt": "string" }`
- **Errors**: 400 (invalid URL), 422 (unsupported event)
- [ ] **API-ITEM-1.10 [Webhook Delivery]**:
- **Method**: POST (outgoing to registered URL)
- **Path**: `{registered_url}`
- **Headers**: `X-Webhook-Signature` (HMAC-SHA256 of body using secret), `X-Webhook-Event` (event type), `X-Webhook-Id` (unique delivery ID)
- **Request Schema**: `{ "event": "order.shipped", "data": { "orderId": "string", "status": "shipped", "trackingNumber": "string" }, "occurredAt": "string" }`
- **Retry Policy**: 3 retries with exponential backoff (1s, 5s, 30s), then dead-letter queue
---
## Proposed Code Changes
### File Block: `openapi.yaml` (Excerpt)
```yaml
openapi: 3.0.3
info:
title: ShopSphere API
version: 1.0.0
description: E-commerce API for products, orders, and inventory
servers:
- url: https://api.shopsphere.com/v1
description: Production
- url: https://staging-api.shopsphere.com/v1
description: Staging
security:
- bearerAuth: []
paths:
/products:
get:
summary: List products with filtering and pagination
parameters:
- name: category
in: query
schema: { type: string }
- name: price_min
in: query
schema: { type: number, minimum: 0 }
- name: cursor
in: query
schema: { type: string }
- name: limit
in: query
schema: { type: integer, default: 20, maximum: 100 }
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ProductList'
/orders:
post:
summary: Create a new order
security:
- bearerAuth: []
parameters:
- name: Idempotency-Key
in: header
required: true
schema: { type: string, format: uuid }
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderCreate'
responses:
'201':
description: Order created
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'409':
description: Duplicate idempotency key
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
Product:
type: object
properties:
id: { type: string, format: uuid }
name: { type: string }
price: { type: number, format: float }
currency: { type: string, enum: [USD, EUR, GBP] }
Order:
type: object
properties:
id: { type: string, format: uuid }
status: { type: string, enum: [pending, confirmed, shipped, delivered, cancelled] }
totalAmount: { type: number }
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
OrderItem:
type: object
properties:
productId: { type: string, format: uuid }
quantity: { type: integer, minimum: 1 }
unitPrice: { type: number }
```
### File Block: `error-handler.js` (Helper)
```javascript
// Standardized error response builder
function buildErrorResponse(statusCode, code, message, details = [], correlationId) {
return {
statusCode,
body: JSON.stringify({
error: {
code,
message,
details,
correlation_id: correlationId
}
}),
headers: {
'Content-Type': 'application/json',
'X-Correlation-ID': correlationId
}
};
}
// Usage in route handler
app.post('/v1/orders', (req, res) => {
const correlationId = req.headers['x-correlation-id'] || crypto.randomUUID();
try {
// ... validation logic
} catch (err) {
if (err.code === 'VALIDATION_ERROR') {
res.status(400).send(buildErrorResponse(400, 'VALIDATION_ERROR', 'Invalid request body', err.details, correlationId));
}
}
});
```
### File Block: `rate-limiter.js` (Helper)
```javascript
// Redis-based rate limiter
const redis = require('redis');
const client = redis.createClient();
async function rateLimit(req, res, next) {
const key = req.apiKey || req.user?.id || req.ip;
const limit = req.apiKey ? 1000 : 100; // per-minute limits
const current = await client.incr(`rl:${key}:${Math.floor(Date.now() / 60000)}`);
if (current === 1) {
await client.expire(`rl:${key}:${Math.floor(Date.now() / 60000)}`, 60);
}
if (current > limit) {
res.set('Retry-After', '60');
return res.status(429).send(buildErrorResponse(429, 'RATE_LIMITED', 'Too many requests', [], req.headers['x-correlation-id']));
}
res.set('X-RateLimit-Limit', limit);
res.set('X-RateLimit-Remaining', limit - current);
next();
}
```
---
## Commands
### Local Development
```bash
# Validate OpenAPI spec
npx @redocly/cli lint openapi.yaml
# Run mock server for testing
npx @stoplight/prism-cli mock openapi.yaml
# Run API tests
npm test
# Start development server
npm run dev
```
### CI Pipeline
```bash
# In CI (GitHub Actions or similar)
npx @redocly/cli lint openapi.yaml
npm run test:coverage
npm run build
```
---
## Quality Assurance Task Checklist
- [x] All endpoints follow consistent naming conventions (kebab-case URLs, camelCase JSON) and HTTP semantics (GET for read, POST for create, PATCH for partial update, DELETE for remove)
- [x] OpenAPI 3.0 specification is complete with schemas, examples, and security schemes; validates with `redocly lint`
- [x] Error responses are standardized with proper status codes (400, 401, 403, 404, 409, 422, 429, 500) and correlation IDs
- [x] Authentication (OAuth 2.0 JWT) and authorization (scopes) documented for every endpoint in the OpenAPI spec
- [x] Pagination (cursor-based) implemented for all collection endpoints (`/products`, `/orders`, `/customers`)
- [x] Filtering (`?category=`, `?price_min=`) and sorting (`?sort=-price`) supported on list endpoints
- [x] Caching strategy defined with ETags (conditional GET) and Cache-Control headers (`public, max-age=300` for products, `private, no-store` for customer data)
- [x] Breaking changes have migration paths: versioning via `/v1/` URI prefix, deprecation notices in changelog, sunset headers for old versions
- [x] Idempotency implemented for POST /orders via `Idempotency-Key` header with 24-hour storage
- [x] Rate limiting implemented per-user, per-API-key, and per-IP with `Retry-After` headers
- [x] Webhook signatures (HMAC-SHA256) verified on delivery with retry policy
- [x] Field selection (`?fields=`) supported to reduce payload sizes
- [x] Compression (gzip, brotli) enabled via `Accept-Encoding` header handling
- [x] HATEOAS links included in order responses (`self`, `cancel`, `shipment`) for discoverability
- [x] CORS configured for allowed origins (`app.shopsphere.com`, `admin.shopsphere.com`) with proper methods and headers
---
## Execution Reminders
- **API as Developer UI**: All endpoints prioritize consistency (naming, error format, pagination) to minimize learning curve for consumers.
- **Stable Contracts**: Versioning from day one (`/v1/`), no breaking changes without major version bump, deprecation timeline of 6 months minimum.
- **REST Purism vs Practicality**: Used PATCH for partial updates (order cancellation) rather than PUT to avoid full-body requirements; used POST for login (not a resource) as pragmatic exception.
- **Complete Documentation**: OpenAPI spec includes examples for every request/response pair, auth setup guide, and changelog.
- **Idempotency**: POST /orders requires `Idempotency-Key`; all GET/PUT/DELETE are safe/idempotent by design.
- **Circular Dependencies**: Avoided by keeping `order-items` nested under orders, not exposing standalone item endpoints.
- **Security Gaps**: Addressed via rate limiting, API key hashing, JWT expiry (1 hour), refresh token rotation, and webhook signature verification.
Melde dich an, um den vollständigen Prompt zu sehen
Weiter mit:
Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz
Verwendung
Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.
Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.
Diskussion
0 Kommentare