Design RESTful API endpoints with proper resource modeling, HTTP methods, and URL structure. Use when creating REST APIs, designing endpoints, or structuring API resources.
Design RESTful APIs with proper resource modeling and endpoint structure.
Use resource-based URLs with plural nouns, proper HTTP methods, and consistent patterns.
Resources, not actions:
Good: GET /users, POST /users
Bad: GET /getUsers, POST /createUser
Use HTTP methods correctly:
Use plural nouns:
Good: /products, /orders
Bad: /product, /order
Identify resources:
Design URL structure:
/api/v1/resources
/api/v1/resources/{id}
/api/v1/resources/{id}/sub-resources
Example - Blog API:
GET /api/v1/posts # List posts
POST /api/v1/posts # Create post
GET /api/v1/posts/{id} # Get post
PUT /api/v1/posts/{id} # Replace post
PATCH /api/v1/posts/{id} # Update post
DELETE /api/v1/posts/{id} # Delete post
GET /api/v1/posts/{id}/comments # List comments
POST /api/v1/posts/{id}/comments # Create comment
GET - Retrieve resources:
GET /api/v1/users # List all users
GET /api/v1/users/{id} # Get specific user
GET /api/v1/users?role=admin # Filter users
Response:
{
"data": [
{ "id": 1, "name": "John" }
],
"meta": {
"total": 100,
"page": 1
}
}
POST - Create resources:
POST /api/v1/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
Response (201 Created):
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00Z"
}
PUT - Replace resource:
PUT /api/v1/users/{id}
Content-Type: application/json
{
"name": "John Smith",
"email": "john.smith@example.com"
}
PATCH - Partial update:
PATCH /api/v1/users/{id}
Content-Type: application/json
{
"email": "newemail@example.com"
}
DELETE - Remove resource:
DELETE /api/v1/users/{id}
Response (204 No Content or 200 with confirmation)
Filtering:
GET /api/v1/products?category=electronics&price_min=100
Sorting:
GET /api/v1/products?sort=price&order=desc
GET /api/v1/products?sort=-price # Descending
Pagination:
GET /api/v1/products?page=2&per_page=20
GET /api/v1/products?offset=20&limit=20
Field selection:
GET /api/v1/users?fields=id,name,email
Search:
GET /api/v1/products?q=laptop
One level (recommended):
GET /api/v1/users/{id}/orders
POST /api/v1/users/{id}/orders
Avoid deep nesting:
Bad: /api/v1/users/{id}/orders/{id}/items/{id}/reviews
Better: /api/v1/reviews?item_id={id}
Alternative - flat with filters:
GET /api/v1/orders?user_id={id}
GET /api/v1/comments?post_id={id}
Success response:
{
"data": {
"id": 1,
"name": "Product"
},
"meta": {
"timestamp": "2024-01-01T00:00:00Z"
}
}
List response:
{
"data": [
{ "id": 1, "name": "Item 1" },
{ "id": 2, "name": "Item 2" }
],
"meta": {
"total": 100,
"page": 1,
"per_page": 20
},
"links": {
"self": "/api/v1/items?page=1",
"next": "/api/v1/items?page=2",
"prev": null
}
}
Error response:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}
Success:
Client errors:
Server errors:
URL versioning (recommended):
/api/v1/users
/api/v2/users
Header versioning:
GET /api/users
Accept: application/vnd.myapi.v1+json
Query parameter:
GET /api/users?version=1
JWT Bearer token:
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
API Key:
GET /api/v1/users
X-API-Key: your-api-key-here
Basic Auth:
GET /api/v1/users
Authorization: Basic base64(username:password)
Include headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
Response when exceeded (429):
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retry_after": 60
}
}
Include links to related resources:
{
"id": 1,
"name": "Product",
"links": {
"self": "/api/v1/products/1",
"category": "/api/v1/categories/5",
"reviews": "/api/v1/products/1/reviews"
}
}
Bulk create:
POST /api/v1/users/bulk
Content-Type: application/json
{
"users": [
{ "name": "User 1" },
{ "name": "User 2" }
]
}
Bulk update:
PATCH /api/v1/users/bulk
Content-Type: application/json
{
"updates": [
{ "id": 1, "status": "active" },
{ "id": 2, "status": "inactive" }
]
}
Long-running operation:
POST /api/v1/reports
Response: 202 Accepted
{
"job_id": "abc123",
"status": "processing",
"status_url": "/api/v1/jobs/abc123"
}
Check status:
GET /api/v1/jobs/abc123
{
"status": "completed",
"result_url": "/api/v1/reports/xyz789"
}
Single file:
POST /api/v1/files
Content-Type: multipart/form-data
file: [binary data]
With metadata:
POST /api/v1/documents
Content-Type: multipart/form-data
file: [binary data]
title: "Document Title"
category: "reports"
Register webhook:
POST /api/v1/webhooks
{
"url": "https://example.com/webhook",
"events": ["order.created", "order.updated"]
}
GET /api/health
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2024-01-01T00:00:00Z"
}
Products:
GET /api/v1/products
POST /api/v1/products
GET /api/v1/products/{id}
PUT /api/v1/products/{id}
DELETE /api/v1/products/{id}
GET /api/v1/products/{id}/reviews
Orders:
GET /api/v1/orders
POST /api/v1/orders
GET /api/v1/orders/{id}
PATCH /api/v1/orders/{id}
GET /api/v1/orders/{id}/items
Customers:
GET /api/v1/customers
POST /api/v1/customers
GET /api/v1/customers/{id}
GET /api/v1/customers/{id}/orders
Cart:
GET /api/v1/cart
POST /api/v1/cart/items
DELETE /api/v1/cart/items/{id}
POST /api/v1/cart/checkout
Use consistent naming:
/order-itemsInclude metadata:
Validate input:
Handle errors gracefully:
Document everything:
Unclear resource boundaries:
Deep nesting:
Inconsistent responses:
下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer