cursor-kit-cli 1.2.0-beta → 1.2.0-beta.3
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/bin/cursor-reinstall-instance.sh +102 -0
- package/dist/cli.cjs +366 -69
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +367 -70
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +39 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +33 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/commands/docs.md +5 -3
- package/templates/commands/explain.md +5 -3
- package/templates/commands/fix.md +5 -3
- package/templates/commands/implement.md +5 -3
- package/templates/commands/refactor.md +5 -3
- package/templates/commands/review.md +5 -3
- package/templates/commands/test.md +5 -3
- package/templates/manifest.json +11 -8
- package/templates/rules/git.mdc +0 -2
- package/templates/rules/toc.mdc +17 -9
- package/templates/skills/aesthetic/SKILL.md +121 -0
- package/templates/skills/aesthetic/assets/design-guideline-template.md +163 -0
- package/templates/skills/aesthetic/assets/design-story-template.md +135 -0
- package/templates/skills/aesthetic/references/design-principles.md +62 -0
- package/templates/skills/aesthetic/references/design-resources.md +75 -0
- package/templates/skills/aesthetic/references/micro-interactions.md +53 -0
- package/templates/skills/aesthetic/references/storytelling-design.md +50 -0
- package/templates/skills/backend-development/SKILL.mdc +95 -0
- package/templates/skills/backend-development/references/backend-api-design.md +495 -0
- package/templates/skills/backend-development/references/backend-architecture.md +454 -0
- package/templates/skills/backend-development/references/backend-authentication.md +338 -0
- package/templates/skills/backend-development/references/backend-code-quality.md +659 -0
- package/templates/skills/backend-development/references/backend-debugging.md +904 -0
- package/templates/skills/backend-development/references/backend-devops.md +494 -0
- package/templates/skills/backend-development/references/backend-mindset.md +387 -0
- package/templates/skills/backend-development/references/backend-performance.md +397 -0
- package/templates/skills/backend-development/references/backend-security.md +290 -0
- package/templates/skills/backend-development/references/backend-technologies.md +256 -0
- package/templates/skills/backend-development/references/backend-testing.md +429 -0
- package/templates/skills/frontend-design/SKILL.mdc +41 -0
- package/templates/skills/frontend-design/references/animejs.md +396 -0
- package/templates/skills/frontend-development/SKILL.mdc +399 -0
- package/templates/skills/frontend-development/resources/common-patterns.md +331 -0
- package/templates/skills/frontend-development/resources/complete-examples.md +872 -0
- package/templates/skills/frontend-development/resources/component-patterns.md +502 -0
- package/templates/skills/frontend-development/resources/data-fetching.md +767 -0
- package/templates/skills/frontend-development/resources/file-organization.md +502 -0
- package/templates/skills/frontend-development/resources/loading-and-error-states.md +501 -0
- package/templates/skills/frontend-development/resources/performance.md +406 -0
- package/templates/skills/frontend-development/resources/routing-guide.md +364 -0
- package/templates/skills/frontend-development/resources/styling-guide.md +428 -0
- package/templates/skills/frontend-development/resources/typescript-standards.md +418 -0
- package/templates/skills/problem-solving/SKILL.mdc +96 -0
- package/templates/skills/problem-solving/references/attribution.md +69 -0
- package/templates/skills/problem-solving/references/collision-zone-thinking.md +79 -0
- package/templates/skills/problem-solving/references/inversion-exercise.md +91 -0
- package/templates/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
- package/templates/skills/problem-solving/references/scale-game.md +95 -0
- package/templates/skills/problem-solving/references/simplification-cascades.md +80 -0
- package/templates/skills/problem-solving/references/when-stuck.md +72 -0
- package/templates/skills/research/SKILL.mdc +168 -0
- package/templates/skills/sequential-thinking/.env.example +8 -0
- package/templates/skills/sequential-thinking/README.md +183 -0
- package/templates/skills/sequential-thinking/SKILL.mdc +94 -0
- package/templates/skills/sequential-thinking/package.json +31 -0
- package/templates/skills/sequential-thinking/references/advanced-strategies.md +79 -0
- package/templates/skills/sequential-thinking/references/advanced-techniques.md +76 -0
- package/templates/skills/sequential-thinking/references/core-patterns.md +95 -0
- package/templates/skills/sequential-thinking/references/examples-api.md +88 -0
- package/templates/skills/sequential-thinking/references/examples-architecture.md +94 -0
- package/templates/skills/sequential-thinking/references/examples-debug.md +90 -0
- package/templates/skills/sequential-thinking/scripts/format-thought.js +159 -0
- package/templates/skills/sequential-thinking/scripts/process-thought.js +236 -0
- package/templates/skills/sequential-thinking/tests/format-thought.test.js +133 -0
- package/templates/skills/sequential-thinking/tests/process-thought.test.js +215 -0
- package/templates/skills/ui-styling/LICENSE.txt +202 -0
- package/templates/skills/ui-styling/SKILL.mdc +321 -0
- package/templates/skills/ui-styling/references/canvas-design-system.md +320 -0
- package/templates/skills/ui-styling/references/shadcn-accessibility.md +471 -0
- package/templates/skills/ui-styling/references/shadcn-components.md +424 -0
- package/templates/skills/ui-styling/references/shadcn-theming.md +373 -0
- package/templates/skills/ui-styling/references/tailwind-customization.md +483 -0
- package/templates/skills/ui-styling/references/tailwind-responsive.md +382 -0
- package/templates/skills/ui-styling/references/tailwind-utilities.md +455 -0
- package/templates/rules/frontend-design.mdc +0 -48
- package/templates/rules/performance.mdc +0 -54
- package/templates/rules/react.mdc +0 -58
- package/templates/rules/security.mdc +0 -50
- package/templates/rules/testing.mdc +0 -54
- package/templates/rules/typescript.mdc +0 -36
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
# Backend API Design
|
|
2
|
+
|
|
3
|
+
Comprehensive guide to designing RESTful, GraphQL, and gRPC APIs with best practices (2025).
|
|
4
|
+
|
|
5
|
+
## REST API Design
|
|
6
|
+
|
|
7
|
+
### Resource-Based URLs
|
|
8
|
+
|
|
9
|
+
**Good:**
|
|
10
|
+
```
|
|
11
|
+
GET /api/v1/users # List users
|
|
12
|
+
GET /api/v1/users/:id # Get specific user
|
|
13
|
+
POST /api/v1/users # Create user
|
|
14
|
+
PUT /api/v1/users/:id # Update user (full)
|
|
15
|
+
PATCH /api/v1/users/:id # Update user (partial)
|
|
16
|
+
DELETE /api/v1/users/:id # Delete user
|
|
17
|
+
|
|
18
|
+
GET /api/v1/users/:id/posts # Get user's posts
|
|
19
|
+
POST /api/v1/users/:id/posts # Create post for user
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Bad (Avoid):**
|
|
23
|
+
```
|
|
24
|
+
GET /api/v1/getUser?id=123 # RPC-style, not RESTful
|
|
25
|
+
POST /api/v1/createUser # Verb in URL
|
|
26
|
+
GET /api/v1/user-posts # Unclear relationship
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### HTTP Status Codes (Meaningful Responses)
|
|
30
|
+
|
|
31
|
+
**Success:**
|
|
32
|
+
- `200 OK` - Successful GET, PUT, PATCH
|
|
33
|
+
- `201 Created` - Successful POST (resource created)
|
|
34
|
+
- `204 No Content` - Successful DELETE
|
|
35
|
+
|
|
36
|
+
**Client Errors:**
|
|
37
|
+
- `400 Bad Request` - Invalid input/validation error
|
|
38
|
+
- `401 Unauthorized` - Missing or invalid authentication
|
|
39
|
+
- `403 Forbidden` - Authenticated but not authorized
|
|
40
|
+
- `404 Not Found` - Resource doesn't exist
|
|
41
|
+
- `409 Conflict` - Resource conflict (duplicate email)
|
|
42
|
+
- `422 Unprocessable Entity` - Validation error (detailed)
|
|
43
|
+
- `429 Too Many Requests` - Rate limit exceeded
|
|
44
|
+
|
|
45
|
+
**Server Errors:**
|
|
46
|
+
- `500 Internal Server Error` - Generic server error
|
|
47
|
+
- `502 Bad Gateway` - Upstream service error
|
|
48
|
+
- `503 Service Unavailable` - Temporary downtime
|
|
49
|
+
- `504 Gateway Timeout` - Upstream service timeout
|
|
50
|
+
|
|
51
|
+
### Request/Response Format
|
|
52
|
+
|
|
53
|
+
**Request:**
|
|
54
|
+
```typescript
|
|
55
|
+
POST /api/v1/users
|
|
56
|
+
Content-Type: application/json
|
|
57
|
+
|
|
58
|
+
{
|
|
59
|
+
"email": "user@example.com",
|
|
60
|
+
"name": "John Doe",
|
|
61
|
+
"age": 30
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Success Response:**
|
|
66
|
+
```typescript
|
|
67
|
+
HTTP/1.1 201 Created
|
|
68
|
+
Content-Type: application/json
|
|
69
|
+
Location: /api/v1/users/123
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
"id": "123",
|
|
73
|
+
"email": "user@example.com",
|
|
74
|
+
"name": "John Doe",
|
|
75
|
+
"age": 30,
|
|
76
|
+
"createdAt": "2025-01-09T12:00:00Z",
|
|
77
|
+
"updatedAt": "2025-01-09T12:00:00Z"
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Error Response:**
|
|
82
|
+
```typescript
|
|
83
|
+
HTTP/1.1 400 Bad Request
|
|
84
|
+
Content-Type: application/json
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
"error": {
|
|
88
|
+
"code": "VALIDATION_ERROR",
|
|
89
|
+
"message": "Invalid input data",
|
|
90
|
+
"details": [
|
|
91
|
+
{
|
|
92
|
+
"field": "email",
|
|
93
|
+
"message": "Invalid email format",
|
|
94
|
+
"value": "invalid-email"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"field": "age",
|
|
98
|
+
"message": "Age must be between 18 and 120",
|
|
99
|
+
"value": 15
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"timestamp": "2025-01-09T12:00:00Z",
|
|
103
|
+
"path": "/api/v1/users"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Pagination
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Request
|
|
112
|
+
GET /api/v1/users?page=2&limit=50
|
|
113
|
+
|
|
114
|
+
// Response
|
|
115
|
+
{
|
|
116
|
+
"data": [...],
|
|
117
|
+
"pagination": {
|
|
118
|
+
"page": 2,
|
|
119
|
+
"limit": 50,
|
|
120
|
+
"total": 1234,
|
|
121
|
+
"totalPages": 25,
|
|
122
|
+
"hasNext": true,
|
|
123
|
+
"hasPrev": true
|
|
124
|
+
},
|
|
125
|
+
"links": {
|
|
126
|
+
"first": "/api/v1/users?page=1&limit=50",
|
|
127
|
+
"prev": "/api/v1/users?page=1&limit=50",
|
|
128
|
+
"next": "/api/v1/users?page=3&limit=50",
|
|
129
|
+
"last": "/api/v1/users?page=25&limit=50"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Filtering and Sorting
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
GET /api/v1/users?status=active&role=admin&sort=-createdAt,name&limit=20
|
|
138
|
+
|
|
139
|
+
# Filters: status=active AND role=admin
|
|
140
|
+
# Sort: createdAt DESC, name ASC
|
|
141
|
+
# Limit: 20 results
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### API Versioning Strategies
|
|
145
|
+
|
|
146
|
+
**URL Versioning (Most Common):**
|
|
147
|
+
```
|
|
148
|
+
/api/v1/users
|
|
149
|
+
/api/v2/users
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Header Versioning:**
|
|
153
|
+
```
|
|
154
|
+
GET /api/users
|
|
155
|
+
Accept: application/vnd.myapi.v2+json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Query Parameter:**
|
|
159
|
+
```
|
|
160
|
+
/api/users?version=2
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Recommendation:** URL versioning for simplicity and discoverability
|
|
164
|
+
|
|
165
|
+
## GraphQL API Design
|
|
166
|
+
|
|
167
|
+
### Schema Definition
|
|
168
|
+
|
|
169
|
+
```graphql
|
|
170
|
+
type User {
|
|
171
|
+
id: ID!
|
|
172
|
+
email: String!
|
|
173
|
+
name: String!
|
|
174
|
+
posts: [Post!]!
|
|
175
|
+
createdAt: DateTime!
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
type Post {
|
|
179
|
+
id: ID!
|
|
180
|
+
title: String!
|
|
181
|
+
content: String!
|
|
182
|
+
author: User!
|
|
183
|
+
published: Boolean!
|
|
184
|
+
createdAt: DateTime!
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
type Query {
|
|
188
|
+
user(id: ID!): User
|
|
189
|
+
users(limit: Int = 50, offset: Int = 0): [User!]!
|
|
190
|
+
post(id: ID!): Post
|
|
191
|
+
posts(authorId: ID, published: Boolean): [Post!]!
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
type Mutation {
|
|
195
|
+
createUser(input: CreateUserInput!): User!
|
|
196
|
+
updateUser(id: ID!, input: UpdateUserInput!): User!
|
|
197
|
+
deleteUser(id: ID!): Boolean!
|
|
198
|
+
|
|
199
|
+
createPost(input: CreatePostInput!): Post!
|
|
200
|
+
publishPost(id: ID!): Post!
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
input CreateUserInput {
|
|
204
|
+
email: String!
|
|
205
|
+
name: String!
|
|
206
|
+
password: String!
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
input UpdateUserInput {
|
|
210
|
+
email: String
|
|
211
|
+
name: String
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Queries
|
|
216
|
+
|
|
217
|
+
```graphql
|
|
218
|
+
# Flexible data fetching - client specifies exactly what they need
|
|
219
|
+
query {
|
|
220
|
+
user(id: "123") {
|
|
221
|
+
id
|
|
222
|
+
name
|
|
223
|
+
email
|
|
224
|
+
posts {
|
|
225
|
+
id
|
|
226
|
+
title
|
|
227
|
+
published
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# With variables
|
|
233
|
+
query GetUser($userId: ID!) {
|
|
234
|
+
user(id: $userId) {
|
|
235
|
+
id
|
|
236
|
+
name
|
|
237
|
+
posts(published: true) {
|
|
238
|
+
title
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Mutations
|
|
245
|
+
|
|
246
|
+
```graphql
|
|
247
|
+
mutation CreateUser($input: CreateUserInput!) {
|
|
248
|
+
createUser(input: $input) {
|
|
249
|
+
id
|
|
250
|
+
email
|
|
251
|
+
name
|
|
252
|
+
createdAt
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
# Variables
|
|
257
|
+
{
|
|
258
|
+
"input": {
|
|
259
|
+
"email": "user@example.com",
|
|
260
|
+
"name": "John Doe",
|
|
261
|
+
"password": "SecurePass123!"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Resolvers (NestJS Example)
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
@Resolver(() => User)
|
|
270
|
+
export class UserResolver {
|
|
271
|
+
constructor(
|
|
272
|
+
private userService: UserService,
|
|
273
|
+
private postService: PostService,
|
|
274
|
+
) {}
|
|
275
|
+
|
|
276
|
+
@Query(() => User, { nullable: true })
|
|
277
|
+
async user(@Args('id') id: string) {
|
|
278
|
+
return this.userService.findById(id);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@Query(() => [User])
|
|
282
|
+
async users(
|
|
283
|
+
@Args('limit', { defaultValue: 50 }) limit: number,
|
|
284
|
+
@Args('offset', { defaultValue: 0 }) offset: number,
|
|
285
|
+
) {
|
|
286
|
+
return this.userService.findAll({ limit, offset });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@Mutation(() => User)
|
|
290
|
+
async createUser(@Args('input') input: CreateUserInput) {
|
|
291
|
+
return this.userService.create(input);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Field resolver - lazy load posts
|
|
295
|
+
@ResolveField(() => [Post])
|
|
296
|
+
async posts(@Parent() user: User) {
|
|
297
|
+
return this.postService.findByAuthorId(user.id);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### GraphQL Best Practices
|
|
303
|
+
|
|
304
|
+
1. **Avoid N+1 Problem** - Use DataLoader
|
|
305
|
+
```typescript
|
|
306
|
+
import DataLoader from 'dataloader';
|
|
307
|
+
|
|
308
|
+
const postLoader = new DataLoader(async (authorIds: string[]) => {
|
|
309
|
+
const posts = await db.posts.findAll({ where: { authorId: authorIds } });
|
|
310
|
+
return authorIds.map(id => posts.filter(p => p.authorId === id));
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// In resolver
|
|
314
|
+
@ResolveField(() => [Post])
|
|
315
|
+
async posts(@Parent() user: User) {
|
|
316
|
+
return this.postLoader.load(user.id);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
2. **Pagination** - Relay-style cursor pagination
|
|
321
|
+
3. **Error Handling** - Return errors in response
|
|
322
|
+
4. **Depth Limiting** - Prevent deeply nested queries
|
|
323
|
+
5. **Query Complexity Analysis** - Limit expensive queries
|
|
324
|
+
|
|
325
|
+
## gRPC API Design
|
|
326
|
+
|
|
327
|
+
### Protocol Buffers Schema
|
|
328
|
+
|
|
329
|
+
```protobuf
|
|
330
|
+
syntax = "proto3";
|
|
331
|
+
|
|
332
|
+
package user;
|
|
333
|
+
|
|
334
|
+
service UserService {
|
|
335
|
+
rpc GetUser (GetUserRequest) returns (User);
|
|
336
|
+
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
|
|
337
|
+
rpc CreateUser (CreateUserRequest) returns (User);
|
|
338
|
+
rpc UpdateUser (UpdateUserRequest) returns (User);
|
|
339
|
+
rpc DeleteUser (DeleteUserRequest) returns (DeleteUserResponse);
|
|
340
|
+
|
|
341
|
+
// Streaming
|
|
342
|
+
rpc StreamUsers (StreamUsersRequest) returns (stream User);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
message User {
|
|
346
|
+
string id = 1;
|
|
347
|
+
string email = 2;
|
|
348
|
+
string name = 3;
|
|
349
|
+
int64 created_at = 4;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
message GetUserRequest {
|
|
353
|
+
string id = 1;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
message ListUsersRequest {
|
|
357
|
+
int32 limit = 1;
|
|
358
|
+
int32 offset = 2;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
message ListUsersResponse {
|
|
362
|
+
repeated User users = 1;
|
|
363
|
+
int32 total = 2;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
message CreateUserRequest {
|
|
367
|
+
string email = 1;
|
|
368
|
+
string name = 2;
|
|
369
|
+
string password = 3;
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Implementation (Node.js)
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import * as grpc from '@grpc/grpc-js';
|
|
377
|
+
import * as protoLoader from '@grpc/proto-loader';
|
|
378
|
+
|
|
379
|
+
const packageDefinition = protoLoader.loadSync('user.proto');
|
|
380
|
+
const userProto = grpc.loadPackageDefinition(packageDefinition).user;
|
|
381
|
+
|
|
382
|
+
// Server implementation
|
|
383
|
+
const server = new grpc.Server();
|
|
384
|
+
|
|
385
|
+
server.addService(userProto.UserService.service, {
|
|
386
|
+
async getUser(call, callback) {
|
|
387
|
+
const user = await userService.findById(call.request.id);
|
|
388
|
+
callback(null, user);
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
async createUser(call, callback) {
|
|
392
|
+
const user = await userService.create(call.request);
|
|
393
|
+
callback(null, user);
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
async streamUsers(call) {
|
|
397
|
+
const users = await userService.findAll();
|
|
398
|
+
for (const user of users) {
|
|
399
|
+
call.write(user);
|
|
400
|
+
}
|
|
401
|
+
call.end();
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
server.bindAsync(
|
|
406
|
+
'0.0.0.0:50051',
|
|
407
|
+
grpc.ServerCredentials.createInsecure(),
|
|
408
|
+
() => server.start()
|
|
409
|
+
);
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### gRPC Benefits
|
|
413
|
+
|
|
414
|
+
- **Performance:** 7-10x faster than REST (binary protocol)
|
|
415
|
+
- **Streaming:** Bi-directional streaming
|
|
416
|
+
- **Type Safety:** Strong typing via Protocol Buffers
|
|
417
|
+
- **Code Generation:** Auto-generate client/server code
|
|
418
|
+
- **Best For:** Internal microservices, high-performance systems
|
|
419
|
+
|
|
420
|
+
## API Design Decision Matrix
|
|
421
|
+
|
|
422
|
+
| Feature | REST | GraphQL | gRPC |
|
|
423
|
+
|---------|------|---------|------|
|
|
424
|
+
| **Use Case** | Public APIs, CRUD | Flexible data fetching | Microservices, performance |
|
|
425
|
+
| **Performance** | Moderate | Moderate | Fastest (7-10x REST) |
|
|
426
|
+
| **Caching** | HTTP caching built-in | Complex | No built-in caching |
|
|
427
|
+
| **Browser Support** | Native | Native | Requires gRPC-Web |
|
|
428
|
+
| **Learning Curve** | Easy | Moderate | Steep |
|
|
429
|
+
| **Streaming** | Limited (SSE) | Subscriptions | Bi-directional |
|
|
430
|
+
| **Tooling** | Excellent | Excellent | Good |
|
|
431
|
+
| **Documentation** | OpenAPI/Swagger | Schema introspection | Protobuf definition |
|
|
432
|
+
|
|
433
|
+
## API Security Checklist
|
|
434
|
+
|
|
435
|
+
- [ ] HTTPS/TLS only (no HTTP)
|
|
436
|
+
- [ ] Authentication (OAuth 2.1, JWT, API keys)
|
|
437
|
+
- [ ] Authorization (RBAC, check permissions)
|
|
438
|
+
- [ ] Rate limiting (prevent abuse)
|
|
439
|
+
- [ ] Input validation (all endpoints)
|
|
440
|
+
- [ ] CORS configured properly
|
|
441
|
+
- [ ] Security headers (CSP, HSTS, X-Frame-Options)
|
|
442
|
+
- [ ] API versioning implemented
|
|
443
|
+
- [ ] Error messages don't leak system info
|
|
444
|
+
- [ ] Audit logging (who did what, when)
|
|
445
|
+
|
|
446
|
+
## API Documentation
|
|
447
|
+
|
|
448
|
+
### OpenAPI/Swagger (REST)
|
|
449
|
+
|
|
450
|
+
```yaml
|
|
451
|
+
openapi: 3.0.0
|
|
452
|
+
info:
|
|
453
|
+
title: User API
|
|
454
|
+
version: 1.0.0
|
|
455
|
+
paths:
|
|
456
|
+
/api/v1/users:
|
|
457
|
+
get:
|
|
458
|
+
summary: List users
|
|
459
|
+
parameters:
|
|
460
|
+
- name: limit
|
|
461
|
+
in: query
|
|
462
|
+
schema:
|
|
463
|
+
type: integer
|
|
464
|
+
default: 50
|
|
465
|
+
responses:
|
|
466
|
+
'200':
|
|
467
|
+
description: Successful response
|
|
468
|
+
content:
|
|
469
|
+
application/json:
|
|
470
|
+
schema:
|
|
471
|
+
type: object
|
|
472
|
+
properties:
|
|
473
|
+
data:
|
|
474
|
+
type: array
|
|
475
|
+
items:
|
|
476
|
+
$ref: '#/components/schemas/User'
|
|
477
|
+
components:
|
|
478
|
+
schemas:
|
|
479
|
+
User:
|
|
480
|
+
type: object
|
|
481
|
+
properties:
|
|
482
|
+
id:
|
|
483
|
+
type: string
|
|
484
|
+
email:
|
|
485
|
+
type: string
|
|
486
|
+
name:
|
|
487
|
+
type: string
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## Resources
|
|
491
|
+
|
|
492
|
+
- **REST Best Practices:** https://restfulapi.net/
|
|
493
|
+
- **GraphQL:** https://graphql.org/learn/
|
|
494
|
+
- **gRPC:** https://grpc.io/docs/
|
|
495
|
+
- **OpenAPI:** https://swagger.io/specification/
|