RESTful API 설계 청사진 생성기
Wikiprompt, 무료 프롬프트 백과사전에서
RESTful API 설계 청사진 생성기 API 설계 문서를 생성하되, 엔드포인트, 요청/응답 스키마, 오류 처리, 인증, OpenAPI 사양을 포함하세요.
프롬프트 내용저장
🌐
I notice you've provided a prompt asking me to design an API, but you haven't filled in the project requirements section (API Purpose, Target Users, Core Resources, Authentication Method, Expected Scale).
However, I'll design a comprehensive API for a typical e-commerce platform as a concrete example, since that's a common use case that demonstrates all the patterns well. I'll make reasonable assumptions and note where you'd customize for your specific needs.
---
# E-Commerce Platform API Design Document
## 1. API OVERVIEW
**API Name:** Commerce API
**Version:** v1
**Base URL:** `https://api.example.com/v1`
**Content-Type:** `application/json` (UTF-8)
**API Style:** RESTful (with a few RPC-style endpoints for complex operations)
### Rate Limiting Strategy
- **Default tier:** 100 requests/minute per API key
- **Premium tier:** 1000 requests/minute per API key
- **Burst allowance:** 2x the rate limit for 10-second windows
- **Strategy:** Token bucket algorithm with sliding window for burst handling
---
## 2. AUTHENTICATION & AUTHORIZATION
### Authentication Method: OAuth 2.0 with JWT Access Tokens
**Primary flow:** Authorization Code + PKCE for server-to-server and web apps
**Machine-to-machine:** Client Credentials flow
**Token format:** JWT (RS256 signed)
**Access token lifetime:** 15 minutes
**Refresh token lifetime:** 30 days (rotating)
### Token Structure
```json
{
"iss": "https://auth.example.com",
"sub": "user_12345",
"aud": "api.example.com",
"exp": 1704067200,
"iat": 1704066300,
"scope": "products:read products:write",
"client_id": "client_abc123"
}
```
### Scopes/Permissions Model
| Scope | Description |
|-------|-------------|
| `products:read` | View products |
| `products:write` | Create/update/delete products |
| `orders:read` | View orders |
| `orders:write` | Create/update orders |
| `customers:read` | View customer data |
| `customers:write` | Modify customer data |
| `admin` | Full access (admin only) |
### Auth Headers
```
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
X-API-Key: live_abc123def456
```
### Refresh Token Strategy
- Refresh tokens are single-use and rotate on each refresh
- Refresh token rotation endpoint: `POST /v1/auth/refresh`
- Revocation on password change or security event
- Refresh token stored in HttpOnly cookie for web apps
---
## 3. RESOURCE DESIGN
### Resource: Products
**Description:** Products available for purchase in the catalog
**Relationships:** Belongs to a `Category`, has many `Variants`, has many `Images`
**ID format:** UUID v4 (e.g., `prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d`)
**Endpoints:**
```
GET /products - List products (with pagination, filtering)
GET /products/:id - Get single product
POST /products - Create new product
PUT /products/:id - Full update
PATCH /products/:id - Partial update
DELETE /products/:id - Delete product (soft delete)
GET /products/:id/variants - List product variants
POST /products/:id/variants - Add variant
```
**Data Schema:**
```json
{
"id": "prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"type": "product",
"attributes": {
"name": "Wireless Headphones Pro",
"slug": "wireless-headphones-pro",
"description": "Premium noise-cancelling headphones",
"price": 299.99,
"currency": "USD",
"status": "active",
"category_id": "cat_12345",
"sku": "WH-PRO-001",
"stock_quantity": 150,
"is_featured": true,
"metadata": {
"color": "black",
"weight_kg": 0.25
}
},
"relationships": {
"category": { "data": { "type": "category", "id": "cat_12345" } },
"variants": { "data": [{ "type": "variant", "id": "var_67890" }] }
},
"links": {
"self": "/v1/products/prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
}
}
```
**Field Definitions Table:**
| Field | Type | Required | Description | Constraints |
|-------|------|----------|-------------|-------------|
| id | string | Yes (server-generated) | Unique identifier | UUID v4, prefixed with `prod_` |
| name | string | Yes | Product name | 1-200 chars |
| slug | string | Yes | URL-friendly identifier | Unique, lowercase, hyphens |
| description | string | No | Detailed description | Max 5000 chars |
| price | number | Yes | Unit price | >= 0, max 2 decimal places |
| currency | string | Yes | ISO 4217 currency code | 3-letter code |
| status | string | Yes | Product status | `draft`, `active`, `archived` |
| category_id | string | No | Parent category | Must reference existing category |
| sku | string | No | Stock keeping unit | Unique, max 50 chars |
| stock_quantity | integer | No | Available stock | >= 0 |
| is_featured | boolean | No | Featured product flag | Default: false |
| metadata | object | No | Custom attributes | Key-value pairs, max 20 keys |
| created_at | string | Yes | Creation timestamp | ISO 8601 UTC |
| updated_at | string | Yes | Last update timestamp | ISO 8601 UTC |
---
### Resource: Orders
**Description:** Customer orders containing one or more line items
**Relationships:** Belongs to a `Customer`, has many `LineItems`, has one `Payment`
**ID format:** UUID v4 (e.g., `ord_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d`)
**Endpoints:**
```
GET /orders - List orders (with pagination, filtering)
GET /orders/:id - Get single order
POST /orders - Create new order
PUT /orders/:id - Full update (admin only)
PATCH /orders/:id - Partial update (status changes)
DELETE /orders/:id - Cancel order (soft delete)
POST /orders/:id/capture - Capture payment (RPC-style)
POST /orders/:id/refund - Refund order (RPC-style)
```
**Data Schema:**
```json
{
"id": "ord_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"type": "order",
"attributes": {
"order_number": "ORD-2024-0001",
"status": "pending_payment",
"subtotal": 299.99,
"tax_total": 24.00,
"shipping_total": 10.00,
"total": 333.99,
"currency": "USD",
"customer_id": "cus_12345",
"shipping_address": {
"line1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country": "US"
},
"billing_address": {
"line1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country": "US"
},
"placed_at": "2024-01-15T10:30:00Z"
},
"relationships": {
"customer": { "data": { "type": "customer", "id": "cus_12345" } },
"line_items": { "data": [{ "type": "line_item", "id": "li_67890" }] }
}
}
```
**Field Definitions Table:**
| Field | Type | Required | Description | Constraints |
|-------|------|----------|-------------|-------------|
| id | string | Yes (server-generated) | Unique identifier | UUID v4, prefixed with `ord_` |
| order_number | string | Yes | Human-readable order number | Auto-generated, unique |
| status | string | Yes | Order status | `pending_payment`, `processing`, `shipped`, `delivered`, `cancelled`, `refunded` |
| subtotal | number | Yes | Sum of line items | >= 0 |
| tax_total | number | Yes | Tax amount | >= 0 |
| shipping_total | number | Yes | Shipping cost | >= 0 |
| total | number | Yes | Grand total | subtotal + tax + shipping |
| currency | string | Yes | ISO 4217 currency code | 3-letter code |
| customer_id | string | Yes | Ordering customer | Must reference existing customer |
| shipping_address | object | Yes | Shipping destination | Valid address object |
| billing_address | object | Yes | Billing address | Valid address object |
| placed_at | string | Yes | Order placement time | ISO 8601 UTC |
---
### Resource: Customers
**Description:** Registered users who can place orders
**Relationships:** Has many `Orders`, has many `Addresses`
**ID format:** UUID v4 (e.g., `cus_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d`)
**Endpoints:**
```
GET /customers - List customers (admin only)
GET /customers/:id - Get single customer
POST /customers - Create new customer
PUT /customers/:id - Full update
PATCH /customers/:id - Partial update
DELETE /customers/:id - Delete customer (soft delete)
GET /customers/:id/orders - List customer's orders
```
**Data Schema:**
```json
{
"id": "cus_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"type": "customer",
"attributes": {
"email": "john.doe@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+1-555-123-4567",
"status": "active",
"default_address_id": "addr_12345",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
},
"relationships": {
"orders": { "data": [{ "type": "order", "id": "ord_67890" }] },
"addresses": { "data": [{ "type": "address", "id": "addr_12345" }] }
}
}
```
**Field Definitions Table:**
| Field | Type | Required | Description | Constraints |
|-------|------|----------|-------------|-------------|
| id | string | Yes (server-generated) | Unique identifier | UUID v4, prefixed with `cus_` |
| email | string | Yes | Customer email | Valid email format, unique |
| first_name | string | Yes | First name | 1-100 chars |
| last_name | string | Yes | Last name | 1-100 chars |
| phone | string | No | Contact phone | E.164 format |
| status | string | Yes | Account status | `active`, `disabled`, `deleted` |
| default_address_id | string | No | Default shipping address | Must reference existing address |
| created_at | string | Yes | Creation timestamp | ISO 8601 UTC |
| updated_at | string | Yes | Last update timestamp | ISO 8601 UTC |
---
## 4. REQUEST/RESPONSE FORMATS
### Standard Success Response
```json
{
"data": {
"id": "prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"type": "product",
"attributes": {
"name": "Wireless Headphones Pro",
"price": 299.99
}
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2024-01-15T10:30:00Z",
"api_version": "v1"
}
}
```
### List Response (with pagination)
```json
{
"data": [
{
"id": "prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"type": "product",
"attributes": {
"name": "Wireless Headphones Pro",
"price": 299.99
}
}
],
"pagination": {
"total": 100,
"page": 1,
"per_page": 20,
"total_pages": 5,
"next_cursor": "eyJpZCI6MTAwfQ==",
"has_more": true
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2024-01-15T10:30:00Z"
}
}
```
### Query Parameters for Lists
| Parameter | Type | Description | Example |
|-----------|------|-------------|---------|
| `page` | integer | Page number (offset pagination) | `?page=2` |
| `per_page` | integer | Items per page (max 100) | `?per_page=50` |
| `cursor` | string | Cursor for cursor-based pagination | `?cursor=eyJpZCI6MTAwfQ==` |
| `sort` | string | Field to sort by | `?sort=price` |
| `order` | string | Sort order: `asc` or `desc` | `?order=desc` |
| `filter[field]` | string | Filter by field | `?filter[status]=active` |
| `include` | string | Related resources to embed | `?include=category,variants` |
| `fields` | string | Sparse fieldsets | `?fields=name,price,sku` |
### Curl Examples
**List products with filtering:**
```bash
curl -X GET "https://api.example.com/v1/products?filter[category]=electronics&filter[price][gte]=100&sort=price&order=asc&per_page=20" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json"
```
**Create a new order:**
```bash
curl -X POST "https://api.example.com/v1/orders" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_12345",
"line_items": [
{
"product_id": "prod_67890",
"quantity": 2
}
],
"shipping_address": {
"line1": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country": "US"
}
}'
```
---
## 5. ERROR HANDLING
### Error Response Format
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Email must be a valid email address"
},
{
"field": "price",
"code": "MIN_VALUE",
"message": "Price must be greater than or equal to 0"
}
],
"request_id": "req_abc123",
"documentation_url": "https://api.example.com/docs/errors#VALIDATION_ERROR"
}
}
```
### Standard Error Codes
| HTTP Status | Error Code | Description |
|-------------|------------|-------------|
| 400 | VALIDATION_ERROR | Request validation failed |
| 401 | UNAUTHORIZED | Missing or invalid auth |
| 403 | FORBIDDEN | Valid auth but insufficient permissions |
| 404 | NOT_FOUND | Resource does not exist |
| 409 | CONFLICT | Resource state conflict (e.g., duplicate SKU) |
| 422 | UNPROCESSABLE | Valid syntax but semantic error (e.g., insufficient stock) |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Server error |
| 503 | SERVICE_UNAVAILABLE | Service temporarily unavailable |
### Error Handling Best Practices
- Always include `request_id` for correlation
- Provide actionable error messages
- Include `documentation_url` for developer reference
- Use appropriate HTTP status codes
- Never expose stack traces or internal details
---
## 6. VERSIONING STRATEGY
### Primary: URL Versioning
- **Current version:** `/v1/`
- **Next version:** `/v2/` (when breaking changes needed)
### Secondary: Header Versioning
```
API-Version: 2024-01-15
```
### Deprecation Policy
1. **Deprecation notice:** 6 months before removal
2. **Headers on deprecated endpoints:**
- `Deprecation: true`
- `Sunset: 2024-07-15`
3. **Migration guide:** Published with each deprecation
### Migration Guide Template
```markdown
## Migration Guide: v1 to v2
### Breaking Changes
- [ ] List each breaking change
- [ ] Provide before/after examples
- [ ] Include migration timeline
### New Features
- [ ] Describe new capabilities
- [ ] Show usage examples
### Deprecated Features
- [ ] List deprecated endpoints/fields
- [ ] Provide alternatives
```
---
## 7. PAGINATION DESIGN
### Chosen Approach: Hybrid (Cursor + Offset)
**Primary:** Cursor-based for stable pagination
**Secondary:** Offset-based for simple use cases
**Cursor-based:**
```
GET /products?cursor=eyJpZCI6MTAwfQ==&per_page=20
```
**Offset-based:**
```
GET /products?page=2&per_page=20
```
### Rationale
- **Cursor-based pros:** Stable with data changes, efficient for large datasets, no duplicates/skips
- **Cursor-based cons:** More complex to implement, opaque to clients
- **Offset-based pros:** Simple, intuitive, easy to jump to specific pages
- **Offset-based cons:** Unstable with data changes, inefficient for large offsets
### Implementation Details
- Cursor is base64-encoded JSON: `{"last_id": "prod_12345", "sort_value": "2024-01-15T10:30:00Z"}`
- Default `per_page`: 20, max: 100
- Response includes both `next_cursor` and `page` for flexibility
---
## 8. FILTERING & SEARCH
### Filtering Patterns
```
# Exact match
GET /products?filter[status]=active
# Range (numeric/date)
GET /products?filter[price][gte]=100&filter[price][lte]=500
GET /products?filter[created_at][gte]=2024-01-01
# Multiple values
GET /products?filter[category]=electronics,books
# Nested fields
GET /products?filter[variants.color]=black
# Null/not null
GET /products?filter[description][null]=true
```
### Search
```
# Full-text search
GET /products?search=wireless headphones
# Search with filters
GET /products?search=wireless&filter[category]=electronics
```
### Filter Operators
| Operator | Description | Example |
|----------|-------------|---------|
| `eq` | Equal (default) | `filter[status]=active` |
| `neq` | Not equal | `filter[status][neq]=archived` |
| `gt` | Greater than | `filter[price][gt]=100` |
| `gte` | Greater than or equal | `filter[price][gte]=100` |
| `lt` | Less than | `filter[price][lt]=500` |
| `lte` | Less than or equal | `filter[price][lte]=500` |
| `in` | In list | `filter[status][in]=active,pending` |
| `null` | Is null | `filter[description][null]=true` |
---
## 9. RATE LIMITING
### Rate Limit Tiers
| Tier | Requests/Minute | Burst | Use Case |
|------|----------------|-------|----------|
| Free | 60 | 120 | Development/testing |
| Standard | 300 | 600 | Production apps |
| Premium | 1000 | 2000 | High-volume apps |
| Enterprise | Custom | Custom | Custom SLA |
### Rate Limit Headers
```
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1704067200
```
### 429 Response
```json
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Please retry after 30 seconds.",
"retry_after": 30,
"request_id": "req_abc123"
}
}
```
### Retry-After Header
```
Retry-After: 30
```
---
## 10. WEBHOOKS
### Event Types
| Event | Description | Trigger |
|-------|-------------|---------|
| `order.created` | New order placed | POST /orders |
| `order.updated` | Order status changed | PATCH /orders/:id |
| `order.cancelled` | Order cancelled | DELETE /orders/:id |
| `payment.captured` | Payment captured | POST /orders/:id/capture |
| `payment.refunded` | Payment refunded | POST /orders/:id/refund |
| `product.updated` | Product modified | PATCH /products/:id |
### Webhook Payload Format
```json
{
"id": "wh_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"event_type": "order.created",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"id": "ord_12345",
"type": "order",
"attributes": {
"status": "pending_payment",
"total": 333.99
}
},
"signature": "sha256=abc123def456..."
}
```
### Signature Verification
```python
import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
```
### Retry Policy
- **Retry attempts:** 3 retries with exponential backoff (1min, 5min, 30min)
- **Timeout:** 10 seconds per attempt
- **Failure handling:** After 3 failures, webhook is disabled and admin notified
- **Idempotency:** Include `X-Idempotency-Key` header for deduplication
---
## 11. OPENAPI SPECIFICATION
```yaml
openapi: 3.0.0
info:
title: Commerce API
version: 1.0.0
description: E-commerce platform API for managing products, orders, and customers
contact:
name: API Support
email: api-support@example.com
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging-api.example.com/v1
description: Staging server
security:
- bearerAuth: []
paths:
/products:
get:
summary: List products
description: Returns a paginated list of products with optional filtering
operationId: listProducts
parameters:
- name: page
in: query
description: Page number
schema:
type: integer
minimum: 1
- name: per_page
in: query
description: Items per page
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: sort
in: query
description: Field to sort by
schema:
type: string
enum: [name, price, created_at, updated_at]
- name: order
in: query
description: Sort order
schema:
type: string
enum: [asc, desc]
default: asc
- name: filter[status]
in: query
description: Filter by status
schema:
type: string
enum: [draft, active, archived]
- name: filter[price][gte]
in: query
description: Minimum price
schema:
type: number
minimum: 0
- name: filter[price][lte]
in: query
description: Maximum price
schema:
type: number
minimum: 0
- name: search
in: query
description: Full-text search
schema:
type: string
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Product'
pagination:
$ref: '#/components/schemas/Pagination'
meta:
$ref: '#/components/schemas/Meta'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
post:
summary: Create product
description: Creates a new product
operationId: createProduct
security:
- bearerAuth: []
scopes: [products:write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: Product created
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
/products/{id}:
get:
summary: Get product by ID
description: Returns a single product
operationId: getProduct
parameters:
- name: id
in: path
required: true
description: Product ID
schema:
type: string
pattern: '^prod_[a-f0-9-]{36}$'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
$ref: '#/components/responses/NotFound'
patch:
summary: Update product
description: Partially updates a product
operationId: updateProduct
security:
- bearerAuth: []
scopes: [products:write]
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductUpdate'
responses:
'200':
description: Product updated
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Delete product
description: Soft-deletes a product
operationId: deleteProduct
security:
- bearerAuth: []
scopes: [products:write]
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'204':
description: Product deleted
'404':
$ref: '#/components/responses/NotFound'
/orders:
get:
summary: List orders
description: Returns a paginated list of orders
operationId: listOrders
security:
- bearerAuth: []
scopes: [orders:read]
parameters:
- name: page
in: query
schema:
type: integer
- name: per_page
in: query
schema:
type: integer
- name: filter[status]
in: query
schema:
type: string
enum: [pending_payment, processing, shipped, delivered, cancelled, refunded]
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Order'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create order
description: Creates a new order
operationId: createOrder
security:
- bearerAuth: []
scopes: [orders:write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderCreate'
responses:
'201':
description: Order created
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'422':
description: Unprocessable entity (e.g., insufficient stock)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
Product:
type: object
required: [id, type, attributes]
properties:
id:
type: string
example: "prod_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
type:
type: string
enum: [product]
attributes:
type: object
properties:
name:
type: string
slug:
type: string
description:
type: string
price:
type: number
format: float
currency:
type: string
status:
type: string
enum: [draft, active, archived]
category_id:
type: string
sku:
type: string
stock_quantity:
type: integer
is_featured:
type: boolean
metadata:
type: object
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ProductCreate:
type: object
required: [name, price, currency]
properties:
name:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 5000
price:
type: number
minimum: 0
currency:
type: string
pattern: '^[A-Z]{3}$'
category_id:
type: string
sku:
type: string
maxLength: 50
stock_quantity:
type: integer
minimum: 0
is_featured:
type: boolean
default: false
metadata:
type: object
additionalProperties: true
ProductUpdate:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 5000
price:
type: number
minimum: 0
status:
type: string
enum: [draft, active, archived]
category_id:
type: string
sku:
type: string
maxLength: 50
stock_quantity:
type: integer
minimum: 0
is_featured:
type: boolean
metadata:
type: object
Order:
type: object
required: [id, type, attributes]
properties:
id:
type: string
example: "ord_8f2b9c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
type:
type: string
enum: [order]
attributes:
type: object
properties:
order_number:
type: string
status:
type: string
enum: [pending_payment, processing, shipped, delivered, cancelled, refunded]
subtotal:
type: number
tax_total:
type: number
shipping_total:
type: number
total:
type: number
currency:
type: string
customer_id:
type: string
shipping_address:
$ref: '#/components/schemas/Address'
billing_address:
$ref: '#/components/schemas/Address'
placed_at:
type: string
format: date-time
OrderCreate:
type: object
required: [customer_id, line_items, shipping_address]
properties:
customer_id:
type: string
line_items:
type: array
minItems: 1
items:
type: object
required: [product_id, quantity]
properties:
product_id:
type: string
quantity:
type: integer
minimum: 1
shipping_address:
$ref: '#/components/schemas/Address'
billing_address:
$ref: '#/components/schemas/Address'
Address:
type: object
required: [line1, city, country]
properties:
line1:
type: string
line2:
type: string
city:
type: string
state:
type: string
postal_code:
type: string
country:
type: string
pattern: '^[A-Z]{2}$'
Pagination:
type: object
properties:
total:
type: integer
page:
type: integer
per_page:
type: integer
total_pages:
type: integer
next_cursor:
type: string
has_more:
type: boolean
Meta:
type: object
properties:
request_id:
type: string
timestamp:
type: string
format: date-time
api_version:
type: string
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
code:
type: string
message:
type: string
request_id:
type: string
documentation_url:
type: string
responses:
ValidationError:
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
```
---
## 12. SDK CONSIDERATIONS
### Recommended SDK Patterns
**Language-specific naming conventions:**
| Language | Package Name | Naming Style | Example |
|----------|-------------|--------------|---------|
| Python | `commerce-api` | snake_case | `client.products.list()` |
| JavaScript | `@example/commerce-api` | camelCase | `client.products.list()` |
| Ruby | `commerce_api` | snake_case | `client.products.list` |
| Go | `commerce-api` | camelCase | `client.Products().List()` |
| Java | `com.example.commerce` | camelCase | `client.products().list()` |
### SDK Structure
```
commerce-api/
├── README.md
├── LICENSE
├── setup.py / package.json / Gemfile
├── src/
│ ├── client.py # Main client class
│ ├── resources/
│ │ ├── products.py # Product resource
│ │ ├── orders.py # Order resource
│ │ └── customers.py # Customer resource
│ ├── errors.py # Exception classes
│ ├── pagination.py # Pagination helpers
│ └── auth.py # Authentication handling
└── tests/
├── test_products.py
├── test_orders.py
└── test_auth.py
```
### Error Handling Expectations
```python
# Python SDK example
from commerce_api import Client, CommerceAPIError
client = Client(api_key="live_abc123")
try:
products = client.products.list(
filters={"category": "electronics"},
sort="price",
order="asc"
)
for product in products:
print(f"{product.name}: ${product.price}")
except CommerceAPIError as e:
print(f"Error {e.status_code}: {e.code}")
print(f"Request ID: {e.request_id}")
```
### Pagination Helpers
```python
# Automatic pagination handling
products = client.products.list(per_page=100)
while products.has_more:
products = client.products.list(cursor=products.next_cursor)
# Process products
```
### SDK Best Practices
1. **Automatic retry** with exponential backoff for 429 and 5xx errors
2. **Request timeout** defaults (30s connect, 60s read)
3. **Logging** with request IDs for correlation
4. **Type hints** for all methods and parameters
5. **Comprehensive documentation** with examples
6. **Versioned SDK releases** matching API versions
7. **Async support** for high-concurrency applications
---
## Design Rationale Summary
### Why REST over GraphQL?
- **Simplicity:** REST is well-understood and easy to debug
- **Caching:** HTTP caching works naturally with REST
- **Scalability:** Stateless design scales horizontally
- **Tooling:** Mature ecosystem of tools and libraries
### Why JSON:API Specification?
- **Consistency:** Standardized structure across all resources
- **Relationships:** Clean handling of related resources
- **Sparse fieldsets:** Efficient payload sizes
- **Inclusion:** Reduce N+1 query problems
### Why Hybrid Pagination?
- **Flexibility:** Supports both simple and complex use cases
- **Performance:** Cursor-based for large datasets
- **Developer experience:** Offset-based for simple needs
### Why OAuth 2.0 + JWT?
- **Industry standard:** Well-tested and widely supported
- **Stateless:** JWT allows stateless authentication
- **Scopes:** Granular permission control
- **Refresh tokens:** Secure long-lived sessions
---
This API design provides a complete, production-ready foundation that follows industry best practices while remaining pragmatic and developer-friendly. The design is consistent, well-documented, and includes all necessary components for building a robust e-commerce platform API.
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
참고 자료
- 분류: coding 프롬프트
토론
댓글 0개