@sylix/coworker 2.0.11 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/slash/config.d.ts.map +1 -1
- package/dist/commands/slash/config.js +22 -4
- package/dist/commands/slash/config.js.map +1 -1
- package/dist/core/CoWorkerAgent.d.ts.map +1 -1
- package/dist/core/CoWorkerAgent.js +6 -3
- package/dist/core/CoWorkerAgent.js.map +1 -1
- package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
- package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
- package/dist/skills/defaults/ai-ml/rag.md +276 -0
- package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
- package/dist/skills/defaults/backend-development/api-design.md +285 -0
- package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
- package/dist/skills/defaults/backend-development/async-python.md +237 -0
- package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
- package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
- package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
- package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
- package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
- package/dist/skills/defaults/backend-development/database-design.md +305 -0
- package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
- package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
- package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
- package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
- package/dist/skills/defaults/backend-development/fastapi.md +309 -0
- package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
- package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
- package/dist/skills/defaults/backend-development/microservices.md +284 -0
- package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
- package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
- package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
- package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
- package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
- package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
- package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
- package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
- package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
- package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
- package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
- package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
- package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
- package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
- package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
- package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
- package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
- package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
- package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
- package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
- package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
- package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
- package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
- package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
- package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
- package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
- package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
- package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
- package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
- package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
- package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
- package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
- package/dist/skills/defaults/data-engineering/airflow.md +519 -0
- package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
- package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
- package/dist/skills/defaults/data-engineering/dbt.md +556 -0
- package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
- package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
- package/dist/skills/defaults/data-engineering/spark.md +411 -0
- package/dist/skills/defaults/database/postgresql.md +202 -0
- package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
- package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
- package/dist/skills/defaults/devops/changelog-automation.md +580 -0
- package/dist/skills/defaults/devops/cicd.md +314 -0
- package/dist/skills/defaults/devops/cloud.md +263 -0
- package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
- package/dist/skills/defaults/devops/cost-optimization.md +295 -0
- package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
- package/dist/skills/defaults/devops/docker.md +281 -0
- package/dist/skills/defaults/devops/git-workflows.md +205 -0
- package/dist/skills/defaults/devops/github-actions.md +311 -0
- package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
- package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
- package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
- package/dist/skills/defaults/devops/kubernetes.md +339 -0
- package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
- package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
- package/dist/skills/defaults/devops/observability.md +243 -0
- package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
- package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
- package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
- package/dist/skills/defaults/devops/secrets-management.md +341 -0
- package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
- package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
- package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
- package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
- package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
- package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
- package/dist/skills/defaults/frontend/interaction-design.md +327 -0
- package/dist/skills/defaults/frontend/javascript.md +311 -0
- package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
- package/dist/skills/defaults/frontend/react-native-design.md +440 -0
- package/dist/skills/defaults/frontend/react.md +345 -0
- package/dist/skills/defaults/frontend/responsive-design.md +472 -0
- package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
- package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
- package/dist/skills/defaults/frontend/typescript.md +334 -0
- package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
- package/dist/skills/defaults/frontend/web-component-design.md +279 -0
- package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
- package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
- package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
- package/dist/skills/defaults/kubernetes/gitops.md +280 -0
- package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
- package/dist/skills/defaults/kubernetes/helm.md +343 -0
- package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
- package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
- package/dist/skills/defaults/kubernetes/manifests.md +330 -0
- package/dist/skills/defaults/kubernetes/security.md +337 -0
- package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
- package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
- package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
- package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
- package/dist/skills/defaults/llm-application/langchain.md +259 -0
- package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
- package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
- package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
- package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
- package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
- package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
- package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
- package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
- package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
- package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
- package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
- package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
- package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
- package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
- package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
- package/dist/skills/defaults/security/auditor.md +168 -0
- package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
- package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
- package/dist/skills/defaults/security/mtls-configuration.md +349 -0
- package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
- package/dist/skills/defaults/security/sast-configuration.md +182 -0
- package/dist/skills/defaults/security/security.md +313 -0
- package/dist/skills/defaults/security/stride-analysis.md +273 -0
- package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
- package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
- package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
- package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
- package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
- package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
- package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
- package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
- package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
- package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
- package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
- package/dist/skills/defaults/testing/testing.md +332 -0
- package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
- package/dist/skills/defaults/workflows/track-management.md +592 -0
- package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
- package/dist/skills/index.d.ts +11 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +129 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/utils/character.js +4 -4
- package/dist/utils/character.js.map +1 -1
- package/dist/utils/inputbar.d.ts.map +1 -1
- package/dist/utils/inputbar.js +7 -0
- package/dist/utils/inputbar.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-design
|
|
3
|
+
description: Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Design Principles — CoWorker Edition
|
|
7
|
+
|
|
8
|
+
Build APIs that developers love to use. These principles apply whether you're building REST or GraphQL.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Designing new REST or GraphQL APIs from scratch
|
|
13
|
+
- Refactoring existing APIs for better developer experience
|
|
14
|
+
- Establishing API standards for your team
|
|
15
|
+
- Reviewing API specifications before implementation
|
|
16
|
+
- Creating API documentation
|
|
17
|
+
|
|
18
|
+
## Core Concepts
|
|
19
|
+
|
|
20
|
+
### RESTful Design Fundamentals
|
|
21
|
+
|
|
22
|
+
**Resources are nouns, not verbs:**
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
# Good: Resource-oriented
|
|
26
|
+
GET /api/users # List users
|
|
27
|
+
POST /api/users # Create user
|
|
28
|
+
GET /api/users/{id} # Get specific user
|
|
29
|
+
PUT /api/users/{id} # Replace user
|
|
30
|
+
PATCH /api/users/{id} # Update user fields
|
|
31
|
+
DELETE /api/users/{id} # Delete user
|
|
32
|
+
|
|
33
|
+
# Nested resources
|
|
34
|
+
GET /api/users/{id}/orders # User's orders
|
|
35
|
+
|
|
36
|
+
# Bad: Action-oriented (avoid)
|
|
37
|
+
POST /api/createUser
|
|
38
|
+
POST /api/getUserById
|
|
39
|
+
POST /api/deleteUser
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**HTTP Methods Semantics:**
|
|
43
|
+
|
|
44
|
+
| Method | Purpose | Idempotent | Safe |
|
|
45
|
+
|---------|-----------------|------------|------|
|
|
46
|
+
| GET | Retrieve | Yes | Yes |
|
|
47
|
+
| POST | Create | No | No |
|
|
48
|
+
| PUT | Replace | Yes | No |
|
|
49
|
+
| PATCH | Partial update | No | No |
|
|
50
|
+
| DELETE | Remove | Yes | No |
|
|
51
|
+
|
|
52
|
+
### GraphQL Schema Design
|
|
53
|
+
|
|
54
|
+
```graphql
|
|
55
|
+
# Define types first - this is your contract
|
|
56
|
+
type User {
|
|
57
|
+
id: ID!
|
|
58
|
+
email: String!
|
|
59
|
+
name: String!
|
|
60
|
+
createdAt: DateTime!
|
|
61
|
+
|
|
62
|
+
# Relationships with pagination
|
|
63
|
+
orders(first: Int = 20, after: String): OrderConnection!
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type Order {
|
|
67
|
+
id: ID!
|
|
68
|
+
status: OrderStatus!
|
|
69
|
+
total: Money!
|
|
70
|
+
items: [OrderItem!]!
|
|
71
|
+
user: User!
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Pagination - use cursor-based (Relay spec)
|
|
75
|
+
type OrderConnection {
|
|
76
|
+
edges: [OrderEdge!]!
|
|
77
|
+
pageInfo: PageInfo!
|
|
78
|
+
totalCount: Int!
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type OrderEdge {
|
|
82
|
+
node: Order!
|
|
83
|
+
cursor: String!
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type PageInfo {
|
|
87
|
+
hasNextPage: Boolean!
|
|
88
|
+
hasPreviousPage: Boolean!
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
enum OrderStatus {
|
|
92
|
+
PENDING
|
|
93
|
+
CONFIRMED
|
|
94
|
+
SHIPPED
|
|
95
|
+
DELIVERED
|
|
96
|
+
CANCELLED
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### API Versioning Strategies
|
|
101
|
+
|
|
102
|
+
**URL Versioning (most common):**
|
|
103
|
+
```
|
|
104
|
+
/api/v1/users
|
|
105
|
+
/api/v2/users
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Header Versioning:**
|
|
109
|
+
```
|
|
110
|
+
Accept: application/vnd.api+json; version=1
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## REST Patterns
|
|
114
|
+
|
|
115
|
+
### Pagination Pattern
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from typing import Optional, List
|
|
119
|
+
from pydantic import BaseModel, Field
|
|
120
|
+
|
|
121
|
+
class PaginationParams(BaseModel):
|
|
122
|
+
page: int = Field(1, ge=1)
|
|
123
|
+
page_size: int = Field(20, ge=1, le=100)
|
|
124
|
+
|
|
125
|
+
class PaginatedResponse(BaseModel):
|
|
126
|
+
items: List[dict]
|
|
127
|
+
total: int
|
|
128
|
+
page: int
|
|
129
|
+
page_size: int
|
|
130
|
+
pages: int
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def has_next(self) -> bool:
|
|
134
|
+
return self.page < self.pages
|
|
135
|
+
|
|
136
|
+
# FastAPI endpoint
|
|
137
|
+
@app.get("/api/users", response_model=PaginatedResponse)
|
|
138
|
+
async def list_users(
|
|
139
|
+
page: int = 1,
|
|
140
|
+
page_size: int = 20,
|
|
141
|
+
status: Optional[str] = None
|
|
142
|
+
):
|
|
143
|
+
offset = (page - 1) * page_size
|
|
144
|
+
users = await fetch_users(limit=page_size, offset=offset, status=status)
|
|
145
|
+
total = await count_users(status=status)
|
|
146
|
+
|
|
147
|
+
return PaginatedResponse(
|
|
148
|
+
items=users,
|
|
149
|
+
total=total,
|
|
150
|
+
page=page,
|
|
151
|
+
page_size=page_size,
|
|
152
|
+
pages=(total + page_size - 1) // page_size
|
|
153
|
+
)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Error Handling Pattern
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from fastapi import HTTPException, status
|
|
160
|
+
|
|
161
|
+
class ErrorResponse(BaseModel):
|
|
162
|
+
error: str
|
|
163
|
+
message: str
|
|
164
|
+
details: Optional[dict] = None
|
|
165
|
+
timestamp: str
|
|
166
|
+
|
|
167
|
+
STATUS_CODES = {
|
|
168
|
+
"success": 200,
|
|
169
|
+
"created": 201,
|
|
170
|
+
"bad_request": 400,
|
|
171
|
+
"unauthorized": 401,
|
|
172
|
+
"forbidden": 403,
|
|
173
|
+
"not_found": 404,
|
|
174
|
+
"conflict": 409,
|
|
175
|
+
"unprocessable": 422,
|
|
176
|
+
"internal_error": 500
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
def not_found(resource: str, id: str):
|
|
180
|
+
raise HTTPException(
|
|
181
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
182
|
+
detail={
|
|
183
|
+
"error": "NotFound",
|
|
184
|
+
"message": f"{resource} not found",
|
|
185
|
+
"details": {"id": id}
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### HATEOAS (Hypermedia Links)
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
class UserResponse(BaseModel):
|
|
194
|
+
id: str
|
|
195
|
+
name: str
|
|
196
|
+
email: str
|
|
197
|
+
_links: dict
|
|
198
|
+
|
|
199
|
+
@classmethod
|
|
200
|
+
def from_user(cls, user, base_url: str):
|
|
201
|
+
return cls(
|
|
202
|
+
id=user.id,
|
|
203
|
+
name=user.name,
|
|
204
|
+
email=user.email,
|
|
205
|
+
_links={
|
|
206
|
+
"self": {"href": f"{base_url}/api/users/{user.id}"},
|
|
207
|
+
"orders": {"href": f"{base_url}/api/users/{user.id}/orders"},
|
|
208
|
+
"update": {"href": f"{base_url}/api/users/{user.id}", "method": "PATCH"}
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## GraphQL Patterns
|
|
214
|
+
|
|
215
|
+
### Resolver Pattern with DataLoader
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
from ariadne import QueryType
|
|
219
|
+
from aiodataloader import DataLoader
|
|
220
|
+
|
|
221
|
+
query = QueryType()
|
|
222
|
+
|
|
223
|
+
class OrdersByUserLoader(DataLoader):
|
|
224
|
+
"""Batch load orders to prevent N+1 queries."""
|
|
225
|
+
|
|
226
|
+
async def batch_load_fn(self, user_ids: List[str]) -> List[List[dict]]:
|
|
227
|
+
orders = await fetch_orders_by_user_ids(user_ids)
|
|
228
|
+
orders_by_user = {}
|
|
229
|
+
for order in orders:
|
|
230
|
+
uid = order["user_id"]
|
|
231
|
+
orders_by_user.setdefault(uid, []).append(order)
|
|
232
|
+
return [orders_by_user.get(uid, []) for uid in user_ids]
|
|
233
|
+
|
|
234
|
+
@query.field("users")
|
|
235
|
+
async def resolve_users(obj, info, first: int = 20, after: Optional[str] = None):
|
|
236
|
+
offset = decode_cursor(after) if after else 0
|
|
237
|
+
users = await fetch_users(limit=first + 1, offset=offset)
|
|
238
|
+
|
|
239
|
+
has_next = len(users) > first
|
|
240
|
+
if has_next:
|
|
241
|
+
users = users[:first]
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
"edges": [{"node": u, "cursor": encode_cursor(offset + i)} for i, u in enumerate(users)],
|
|
245
|
+
"pageInfo": {"hasNextPage": has_next}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@user_type.field("orders")
|
|
249
|
+
async def resolve_user_orders(user: dict, info, first: int = 20):
|
|
250
|
+
loader = info.context["loaders"]["orders"]
|
|
251
|
+
orders = await loader.load(user["id"])
|
|
252
|
+
return paginate_orders(orders, first)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Best Practices
|
|
256
|
+
|
|
257
|
+
### REST
|
|
258
|
+
|
|
259
|
+
1. **Consistent naming** - Plural nouns (`/users`, not `/user`)
|
|
260
|
+
2. **Stateless** - Each request contains all needed information
|
|
261
|
+
3. **Correct status codes** - 2xx for success, 4xx client errors, 5xx server errors
|
|
262
|
+
4. **Version from day one** - Plan for breaking changes
|
|
263
|
+
5. **Always paginate** - Never return unbounded collections
|
|
264
|
+
6. **Rate limiting** - Protect your API
|
|
265
|
+
7. **OpenAPI/Swagger** - Document interactively
|
|
266
|
+
|
|
267
|
+
### GraphQL
|
|
268
|
+
|
|
269
|
+
1. **Schema first** - Design before implementing resolvers
|
|
270
|
+
2. **Prevent N+1** - Use DataLoaders
|
|
271
|
+
3. **Validate inputs** - Schema AND resolver level
|
|
272
|
+
4. **Structured errors** - Return errors in mutation payloads
|
|
273
|
+
5. **Cursor pagination** - Follow Relay spec
|
|
274
|
+
6. **Deprecation** - Use `@deprecated` for gradual migration
|
|
275
|
+
7. **Query complexity** - Monitor and limit
|
|
276
|
+
|
|
277
|
+
## Common Pitfalls
|
|
278
|
+
|
|
279
|
+
- Over-fetching/under-fetching in REST (solved by GraphQL with DataLoaders)
|
|
280
|
+
- Breaking changes without versioning
|
|
281
|
+
- Inconsistent error formats
|
|
282
|
+
- Missing rate limits
|
|
283
|
+
- Poor documentation
|
|
284
|
+
- Ignoring HTTP semantics
|
|
285
|
+
- Tight coupling to database schema
|