资源设计 #

什么是资源? #

在 REST 架构中,资源是核心概念。资源是任何可以被命名和引用的信息实体。

text
┌─────────────────────────────────────────────────────────────┐
│                      资源定义                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  资源 = 任何可以被命名的事物                                 │
│                                                             │
│  可以是:                                                    │
│  - 实体对象:用户、商品、订单                               │
│  - 集合:用户列表、商品目录                                 │
│  - 虚拟概念:搜索结果、报表                                 │
│  - 业务流程:支付、审批                                     │
│                                                             │
│  关键特征:                                                  │
│  ✅ 有唯一标识(URI)                                       │
│  ✅ 有状态数据(表述)                                      │
│  ✅ 可被操作(CRUD)                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源识别 #

识别方法 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源识别步骤                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  第一步:分析业务领域                                        │
│  ─────────────────────────────────────────────              │
│  - 系统中有哪些核心实体?                                   │
│  - 实体之间的关系是什么?                                   │
│  - 哪些需要对外暴露?                                       │
│                                                             │
│  示例:电商系统                                              │
│  - 用户(User)                                             │
│  - 商品(Product)                                          │
│  - 订单(Order)                                            │
│  - 购物车(Cart)                                           │
│  - 评论(Review)                                           │
│                                                             │
│  第二步:确定资源类型                                        │
│  ─────────────────────────────────────────────              │
│  - 集合资源:多个资源的集合                                 │
│  - 单个资源:特定标识的资源                                 │
│  - 子资源:属于其他资源的资源                               │
│                                                             │
│  第三步:定义资源属性                                        │
│  ─────────────────────────────────────────────              │
│  - 标识属性:id                                             │
│  - 业务属性:name, email, price                            │
│  - 元数据:createdAt, updatedAt                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源类型详解 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源类型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 集合资源(Collection Resource)                          │
│  ─────────────────────────────────────────────              │
│  定义:一组相同类型资源的集合                                │
│                                                             │
│  URI:/users                                                │
│                                                             │
│  操作:                                                      │
│  GET    /users          获取用户列表                        │
│  POST   /users          创建新用户                          │
│                                                             │
│  2. 单个资源(Singleton Resource)                           │
│  ─────────────────────────────────────────────              │
│  定义:集合中的一个具体资源                                  │
│                                                             │
│  URI:/users/123                                            │
│                                                             │
│  操作:                                                      │
│  GET    /users/123      获取指定用户                        │
│  PUT    /users/123      更新用户                            │
│  DELETE /users/123      删除用户                            │
│                                                             │
│  3. 子资源(Sub-resource)                                   │
│  ─────────────────────────────────────────────              │
│  定义:属于另一个资源的资源                                  │
│                                                             │
│  URI:/users/123/orders                                      │
│                                                             │
│  操作:                                                      │
│  GET    /users/123/orders   获取用户订单                    │
│  POST   /users/123/orders   为用户创建订单                  │
│                                                             │
│  4. 单例子资源(Singleton Sub-resource)                     │
│  ─────────────────────────────────────────────              │
│  定义:一对一关系的子资源                                    │
│                                                             │
│  URI:/users/123/profile                                     │
│                                                             │
│  操作:                                                      │
│  GET    /users/123/profile  获取用户资料                    │
│  PUT    /users/123/profile  更新用户资料                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源命名 #

命名规则 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源命名规则                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  规则一:使用名词                                            │
│  ─────────────────────────────────────────────              │
│  ✅ /users                                                  │
│  ✅ /products                                               │
│  ❌ /getUsers                                               │
│  ❌ /createProduct                                          │
│                                                             │
│  规则二:使用复数形式                                        │
│  ─────────────────────────────────────────────              │
│  ✅ /users                                                  │
│  ✅ /orders                                                 │
│  ❌ /user                                                   │
│  ❌ /order                                                  │
│                                                             │
│  规则三:使用小写字母                                        │
│  ─────────────────────────────────────────────              │
│  ✅ /user-profiles                                          │
│  ✅ /order-items                                            │
│  ❌ /UserProfiles                                           │
│  ❌ /OrderItems                                             │
│                                                             │
│  规则四:使用连字符分隔                                      │
│  ─────────────────────────────────────────────              │
│  ✅ /order-items                                            │
│  ✅ /user-profiles                                          │
│  ❌ /orderItems                                             │
│  ❌ /user_profiles                                          │
│                                                             │
│  规则五:避免文件扩展名                                      │
│  ─────────────────────────────────────────────              │
│  ✅ /users/123                                              │
│  ❌ /users/123.json                                         │
│  ❌ /users/123.xml                                          │
│                                                             │
│  规则六:避免尾部斜杠                                        │
│  ─────────────────────────────────────────────              │
│  ✅ /users                                                  │
│  ❌ /users/                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

命名示例 #

text
┌─────────────────────────────────────────────────────────────┐
│                    命名示例对照                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  业务场景          错误命名              正确命名            │
│  ─────────────────────────────────────────────────────────  │
│  用户管理          /user                /users              │
│                    /getUsers            /users              │
│                    /User                /users              │
│                                                             │
│  订单管理          /order               /orders             │
│                    /orderList           /orders             │
│                    /get-order-list      /orders             │
│                                                             │
│  订单项            /orderItem           /order-items        │
│                    /order_items         /order-items        │
│                    /OrderItem           /order-items        │
│                                                             │
│  用户资料          /userProfile         /user-profiles      │
│                    /user_profile        /user-profiles      │
│                    /UserProfile         /user-profiles      │
│                                                             │
│  购物车            /cart               /carts               │
│                    /shopping-cart      /carts               │
│                    /ShoppingCart       /carts               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源层级设计 #

层级结构 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源层级结构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  第一层:顶级资源                                            │
│  /users                                                     │
│  /products                                                  │
│  /orders                                                    │
│                                                             │
│  第二层:子资源                                              │
│  /users/123/orders                                          │
│  /products/456/reviews                                      │
│  /orders/789/items                                          │
│                                                             │
│  第三层:更深层级(谨慎使用)                                │
│  /users/123/orders/789/items                                │
│                                                             │
│  建议:                                                      │
│  - 层级不超过 3 层                                          │
│  - 过深层级考虑使用查询参数                                 │
│  - 复杂关系考虑独立资源                                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

层级设计示例 #

text
┌─────────────────────────────────────────────────────────────┐
│                    层级设计示例                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  场景:电商系统                                              │
│                                                             │
│  用户资源层级:                                              │
│  /users                                 用户集合            │
│  /users/123                             单个用户            │
│  /users/123/orders                      用户订单            │
│  /users/123/orders/456                  单个订单            │
│  /users/123/profile                     用户资料            │
│  /users/123/addresses                   用户地址            │
│  /users/123/addresses/1                 单个地址            │
│                                                             │
│  商品资源层级:                                              │
│  /products                              商品集合            │
│  /products/456                          单个商品            │
│  /products/456/reviews                  商品评论            │
│  /products/456/images                   商品图片            │
│  /products/456/variants                 商品变体            │
│                                                             │
│  订单资源层级:                                              │
│  /orders                                订单集合            │
│  /orders/789                            单个订单            │
│  /orders/789/items                      订单项              │
│  /orders/789/items/1                    单个订单项          │
│  /orders/789/payments                   支付记录            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

层级设计决策 #

text
┌─────────────────────────────────────────────────────────────┐
│                    层级设计决策指南                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  问题:如何表示资源之间的关系?                              │
│                                                             │
│  方案一:嵌套资源(子资源)                                  │
│  ─────────────────────────────────────────────              │
│  适用场景:                                                  │
│  - 子资源完全属于父资源                                     │
│  - 子资源没有独立存在的意义                                 │
│  - 通常通过父资源访问                                       │
│                                                             │
│  示例:                                                      │
│  /users/123/orders          用户的订单                      │
│  /orders/789/items          订单的订单项                    │
│                                                             │
│  方案二:独立资源 + 关联                                     │
│  ─────────────────────────────────────────────              │
│  适用场景:                                                  │
│  - 资源可以独立存在                                         │
│  - 资源有多种访问方式                                       │
│  - 需要直接访问资源                                         │
│                                                             │
│  示例:                                                      │
│  /orders/789                直接访问订单                    │
│  /orders/789?user_id=123    通过用户过滤订单                │
│  /users/123/orders          通过用户访问订单                │
│                                                             │
│  方案三:使用查询参数                                        │
│  ─────────────────────────────────────────────              │
│  适用场景:                                                  │
│  - 避免层级过深                                             │
│  - 灵活过滤                                                 │
│                                                             │
│  示例:                                                      │
│  /comments?user_id=123&post_id=456                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源标识设计 #

ID 设计 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源标识设计                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  常见 ID 类型:                                              │
│                                                             │
│  1. 自增整数                                                 │
│     /users/1                                                │
│     /users/2                                                │
│                                                             │
│     优点:简单、有序、易读                                  │
│     缺点:可预测、暴露业务量                                │
│                                                             │
│  2. UUID                                                     │
│     /users/550e8400-e29b-41d4-a716-446655440000             │
│                                                             │
│     优点:不可预测、全局唯一                                │
│     缺点:较长、不美观                                      │
│                                                             │
│  3. 雪花算法 ID                                              │
│     /users/1234567890123456789                              │
│                                                             │
│     优点:有序、分布式唯一                                  │
│     缺点:较长                                              │
│                                                             │
│  4. 自定义 ID                                                │
│     /products/iPhone-15-pro                                 │
│     /posts/how-to-design-api                                │
│                                                             │
│     优点:语义化、SEO 友好                                  │
│     缺点:可能冲突、变更困难                                │
│                                                             │
│  推荐:                                                      │
│  - 内部系统:自增整数或雪花 ID                              │
│  - 公开 API:UUID 或自定义 ID                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

URI 模板 #

text
┌─────────────────────────────────────────────────────────────┐
│                    URI 模板                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  基本格式:                                                  │
│  /{resource}/{id}                                           │
│  /{resource}/{id}/{sub-resource}                            │
│  /{resource}/{id}/{sub-resource}/{sub-id}                   │
│                                                             │
│  示例:                                                      │
│  /users                     用户集合                        │
│  /users/{userId}            单个用户                        │
│  /users/{userId}/orders     用户订单集合                    │
│  /users/{userId}/orders/{orderId}  单个订单                 │
│                                                             │
│  参数命名:                                                  │
│  - 使用 camelCase:userId, orderId                         │
│  - 语义清晰:productId, commentId                          │
│  - 避免缩写:userId 而非 uid                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源表述设计 #

表述格式 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源表述格式                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  JSON 格式(推荐):                                         │
│  {                                                          │
│    "id": 123,                                               │
│    "name": "张三",                                          │
│    "email": "zhangsan@example.com",                         │
│    "status": "active",                                      │
│    "createdAt": "2025-01-15T10:30:00Z",                     │
│    "updatedAt": "2025-03-20T15:45:00Z"                      │
│  }                                                          │
│                                                             │
│  XML 格式:                                                  │
│  <?xml version="1.0"?>                                      │
│  <user>                                                     │
│    <id>123</id>                                             │
│    <name>张三</name>                                        │
│    <email>zhangsan@example.com</email>                      │
│  </user>                                                    │
│                                                             │
│  推荐:使用 JSON 格式                                        │
│  - 轻量级                                                   │
│  - 易于解析                                                 │
│  - 广泛支持                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

属性命名规范 #

text
┌─────────────────────────────────────────────────────────────┐
│                    属性命名规范                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  规则一:使用 camelCase                                      │
│  ✅ { "firstName": "张", "lastName": "三" }                 │
│  ❌ { "first_name": "张", "last_name": "三" }               │
│  ❌ { "FirstName": "张", "LastName": "三" }                 │
│                                                             │
│  规则二:语义清晰                                            │
│  ✅ { "createdAt": "...", "updatedAt": "..." }              │
│  ❌ { "ca": "...", "ua": "..." }                            │
│                                                             │
│  规则三:一致性                                              │
│  ✅ 统一使用 "id" 或 "_id"                                  │
│  ✅ 统一使用 "createdAt" 或 "created_at"                    │
│                                                             │
│  规则四:避免冗余                                            │
│  ✅ { "name": "张三" }                                      │
│  ❌ { "userName": "张三" }  // 在用户资源中                  │
│                                                             │
│  规则五:布尔值使用 is/has 前缀                              │
│  ✅ { "isActive": true, "hasPermission": false }            │
│  ❌ { "active": true, "permission": false }                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

标准属性 #

text
┌─────────────────────────────────────────────────────────────┐
│                    标准属性                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  标识属性:                                                  │
│  id              string/number    资源唯一标识              │
│                                                             │
│  时间属性:                                                  │
│  createdAt       string          创建时间(ISO 8601)       │
│  updatedAt       string          更新时间(ISO 8601)       │
│  deletedAt       string          删除时间(软删除)         │
│                                                             │
│  状态属性:                                                  │
│  status          string          资源状态                   │
│  isActive        boolean         是否激活                   │
│                                                             │
│  统计属性:                                                  │
│  totalCount      number          总数                       │
│  pageCount       number          页数                       │
│                                                             │
│  示例:                                                      │
│  {                                                          │
│    "id": 123,                                               │
│    "name": "张三",                                          │
│    "email": "zhangsan@example.com",                         │
│    "status": "active",                                      │
│    "isActive": true,                                        │
│    "createdAt": "2025-01-15T10:30:00Z",                     │
│    "updatedAt": "2025-03-20T15:45:00Z"                      │
│  }                                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源关系设计 #

关系类型 #

text
┌─────────────────────────────────────────────────────────────┐
│                    资源关系类型                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 一对一(One-to-One)                                     │
│  ─────────────────────────────────────────────              │
│  示例:用户 - 用户资料                                       │
│                                                             │
│  /users/123                                                 │
│  /users/123/profile                                         │
│                                                             │
│  表述:                                                      │
│  {                                                          │
│    "id": 123,                                               │
│    "name": "张三",                                          │
│    "profile": {                                             │
│      "avatar": "https://...",                               │
│      "bio": "..."                                           │
│    }                                                        │
│  }                                                          │
│                                                             │
│  2. 一对多(One-to-Many)                                    │
│  ─────────────────────────────────────────────              │
│  示例:用户 - 订单                                           │
│                                                             │
│  /users/123                                                 │
│  /users/123/orders                                          │
│                                                             │
│  表述:                                                      │
│  {                                                          │
│    "id": 123,                                               │
│    "name": "张三",                                          │
│    "orders": [                                              │
│      { "id": 1, "total": 100 },                             │
│      { "id": 2, "total": 200 }                              │
│    ]                                                        │
│  }                                                          │
│                                                             │
│  3. 多对多(Many-to-Many)                                   │
│  ─────────────────────────────────────────────              │
│  示例:学生 - 课程                                           │
│                                                             │
│  /students/123/courses                                      │
│  /courses/456/students                                      │
│                                                             │
│  表述:                                                      │
│  {                                                          │
│    "id": 123,                                               │
│    "name": "张三",                                          │
│    "courses": [                                             │
│      { "id": 1, "name": "数学", "enrolledAt": "..." },      │
│      { "id": 2, "name": "英语", "enrolledAt": "..." }       │
│    ]                                                        │
│  }                                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

关联资源处理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    关联资源处理策略                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  策略一:嵌入资源(Embedding)                               │
│  ─────────────────────────────────────────────              │
│  适用:关联数据量小、频繁一起使用                            │
│                                                             │
│  GET /orders/789                                            │
│  {                                                          │
│    "id": 789,                                               │
│    "total": 1000,                                           │
│    "user": {                                                │
│      "id": 123,                                             │
│      "name": "张三"                                         │
│    }                                                        │
│  }                                                          │
│                                                             │
│  策略二:资源引用(Reference)                               │
│  ─────────────────────────────────────────────              │
│  适用:关联数据量大、独立访问                                │
│                                                             │
│  GET /orders/789                                            │
│  {                                                          │
│    "id": 789,                                               │
│    "total": 1000,                                           │
│    "userId": 123,                                           │
│    "user": {                                                │
│      "href": "/users/123"                                   │
│    }                                                        │
│  }                                                          │
│                                                             │
│  策略三:按需嵌入(Conditional Embedding)                   │
│  ─────────────────────────────────────────────              │
│  适用:灵活控制返回内容                                      │
│                                                             │
│  GET /orders/789?embed=user                                 │
│  {                                                          │
│    "id": 789,                                               │
│    "total": 1000,                                           │
│    "user": {                                                │
│      "id": 123,                                             │
│      "name": "张三"                                         │
│    }                                                        │
│  }                                                          │
│                                                             │
│  GET /orders/789                                            │
│  {                                                          │
│    "id": 789,                                               │
│    "total": 1000,                                           │
│    "userId": 123                                            │
│  }                                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源设计示例 #

电商系统资源设计 #

text
┌─────────────────────────────────────────────────────────────┐
│                    电商系统资源设计                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  用户资源:                                                  │
│  GET    /users                     获取用户列表             │
│  POST   /users                     创建用户                 │
│  GET    /users/{id}                获取用户详情             │
│  PUT    /users/{id}                更新用户                 │
│  DELETE /users/{id}                删除用户                 │
│  GET    /users/{id}/orders         获取用户订单             │
│  GET    /users/{id}/addresses      获取用户地址             │
│  GET    /users/{id}/profile        获取用户资料             │
│                                                             │
│  商品资源:                                                  │
│  GET    /products                  获取商品列表             │
│  POST   /products                  创建商品                 │
│  GET    /products/{id}             获取商品详情             │
│  PUT    /products/{id}             更新商品                 │
│  DELETE /products/{id}             删除商品                 │
│  GET    /products/{id}/reviews     获取商品评论             │
│  GET    /products/{id}/variants    获取商品变体             │
│                                                             │
│  订单资源:                                                  │
│  GET    /orders                    获取订单列表             │
│  POST   /orders                    创建订单                 │
│  GET    /orders/{id}               获取订单详情             │
│  PUT    /orders/{id}               更新订单                 │
│  DELETE /orders/{id}               取消订单                 │
│  GET    /orders/{id}/items         获取订单项               │
│  POST   /orders/{id}/payments      创建支付                 │
│                                                             │
│  购物车资源:                                                │
│  GET    /carts                     获取购物车列表           │
│  POST   /carts                     创建购物车               │
│  GET    /carts/{id}                获取购物车详情           │
│  PUT    /carts/{id}                更新购物车               │
│  DELETE /carts/{id}                清空购物车               │
│  POST   /carts/{id}/items          添加商品到购物车         │
│  DELETE /carts/{id}/items/{itemId} 移除购物车商品           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

资源设计检查清单 #

text
□ 资源识别
  □ 识别了所有核心业务实体
  □ 确定了资源类型(集合/单个/子资源)
  □ 定义了资源属性

□ 资源命名
  □ 使用名词
  □ 使用复数形式
  □ 使用小写字母
  □ 使用连字符分隔
  □ 无文件扩展名
  □ 无尾部斜杠

□ 资源层级
  □ 层级不超过 3 层
  □ 关系表达清晰
  □ 避免过度嵌套

□ 资源标识
  □ 选择合适的 ID 类型
  □ URI 模板清晰

□ 资源表述
  □ 使用 JSON 格式
  □ 属性命名规范
  □ 包含标准属性
  □ 关联资源处理合理

下一步 #

现在你已经了解了资源设计的方法,接下来学习 端点设计,深入了解如何设计完整的 API 端点!

最后更新:2026-03-29