获取首页 Feed

GET /api/v1/feed/home?cursor={cursor}&count=20

Headers:
    Authorization: Bearer {token}

Response:
{
    "code": 0,
    "data": {
        "posts": [
            {
                "post_id": "9876543210",
                "user": {...},
                "content": "微博内容",
                "media": [...],
                "likes_count": 100,
                "comments_count": 50,
                "is_liked": false,
                "created_at": "2024-01-01T12:00:00Z"
            }
        ],
        "next_cursor": "cursor_string",
        "has_more": true
    }
}

给用户返回一个按时间或推荐排序的内容流,并支持高效分页

接口整体设计意图

GET /api/v1/feed/home

这是一个典型的 Feed 流接口(信息流)

  • GET:说明是读取资源,没有副作用 ✅
  • /feed/home:语义清晰,表示“首页时间线”
  • Authorization:说明是个性化 Feed(和用户强相关)

👉 本质:基于用户关注关系 + 推荐系统生成的内容流

分页设计:cursor 模式(重点)

?cursor={cursor}&count=20

cursor 分页的优势
相比传统:

?page=1&page_size=20

cursor 具备:

  • 避免深分页问题(性能好)
  • 适合时间流(Feed)这种不断新增的数据
  • 不会出现数据错乱(翻页时数据插入导致重复/丢失)

👉 特别适用于 Feed 场景(微博、朋友圈)

cursor 通常是:

  • 上一页最后一条数据的某种标记(如时间戳 / ID)
  • 或者服务端生成的 opaque token(加密字符串)

例如:

next_cursor = "1698765432100_9876543210"

可能包含:

  • 时间戳
  • post_id
  1. 第一次请求:
GET /feed/home?count=20

返回:

next_cursor = A
  1. 下一页:
GET /feed/home?cursor=A&count=20

👉 实现的是“从 A 之后继续取”

返回结构设计

  1. posts 内容结构
{
    "post_id": "9876543210",
    "user": {...},
    "content": "...",
    "media": [...],
    "likes_count": 100,
    "comments_count": 50,
    "is_liked": false,
    "created_at": "..."
}

✅ 优点

  • 去范式化(Denormalization)设计
    • user 信息直接嵌入
    • 避免前端再请求用户接口

👉 典型 Feed 优化策略:减少请求次数

字段 作用
post_id 唯一标识
user 作者信息(冗余)
content 文本内容
media 图片/视频
likes_count 点赞数(缓存值)
comments_count 评论数(缓存值)
is_liked 当前用户是否点赞(个性化字段)
created_at 排序依据
  1. 个性化字段
"is_liked": false

这个很关键:

  • 必须基于当前用户计算
  • 通常来自:

👉 Redis / 缓存 / Like Service

  1. 分页控制字段
"next_cursor": "cursor_string",
"has_more": true
  • next_cursor:用于下一页
  • has_more:避免客户端多发请求

👉 比 page 模式更优雅

后端实现思路(核心)

这个接口背后通常是:

1. Feed 生成模式

两种主流:
✅ 1. Push 模式(Fanout on write)

  • 用户发微博时:
    • 推送到粉丝的 Feed 表
  • 查询时:
    • 直接读 Feed 表

👉 优点:读取快
👉 缺点:写放大

✅ 2. Pull 模式(Fanout on read)

  • 查询时:
    • 拉取关注人的内容
    • 再排序

👉 优点:写简单
👉 缺点:读复杂

✅ 3. 混合模式(实际生产)

  • 大 V:pull
  • 普通用户:push

2. 数据来源

Feed 数据可能来自:

  • Follow Service(关注关系)
  • Post Service(内容)
  • Like Service(点赞状态)
  • Cache(Redis)

3. 排序逻辑

可能是:

  • 时间排序(倒序)
  • 推荐算法排序(权重)

性能设计亮点

count=20

  • 控制返回数量
  • 防止接口过载

去范式化
减少请求:

Feed接口 = Post + User + Like状态 一次返回

👉 极大提升前端体验

缓存使用
常见:

  • Feed 缓存(用户时间线)
  • 点赞状态缓存
  • 计数缓存(likes_count)

可能的优化点

字段裁剪(Feed 场景常见)
可以增加:

fields=...

减少流量

增加刷新机制
例如:

since_id / refresh_cursor

用于“下拉刷新”

Feed 类型扩展
比如:

  • 推荐 Feed
  • 关注 Feed
  • 热门 Feed

获取用户微博列表

GET /api/v1/users/{user_id}/posts?cursor={cursor}&count=20

Response:
{
    "code": 0,
    "data": {
        "posts": [...],
        "next_cursor": "cursor_string",
        "has_more": true
    }
}

接口语义

GET /api/v1/users/{user_id}/posts

这是一个非常标准的 RESTful 设计:

  • GET:只读操作 ✅
  • /users/{user_id}:资源归属清晰(某个用户)
  • /posts:这个用户发布的内容集合

👉 本质:查询某个用户的历史发帖记录

和“首页 Feed”的核心区别

维度 用户微博列表 首页 Feed
数据来源 单一用户 多用户 + 推荐
是否个性化 ❌(基本不需要)
排序 时间倒序 时间 / 推荐
实现复杂度 ✅ 简单 ❌ 很复杂

这个接口 = 单表顺序扫描(带分页)

分页设计(依然是 cursor)

?cursor={cursor}&count=20

依然使用 cursor,而不是 page,这点很好。
即使是单用户数据,也有这些问题:

  • 用户持续发微博(数据在变)
  • page 分页会:
    • 出现重复
    • 或漏数据

👉 cursor 能保证:

  • ✅ 稳定分页
  • ✅ 不受新数据插入影响

对于用户 posts,cursor 通常就是:

created_at 或 post_id

例如:

cursor = 最后一条的 post_id

SQL 类似:

SELECT * 
FROM posts
WHERE user_id = ?
  AND post_id < cursor
ORDER BY post_id DESC
LIMIT 20;

👉 非常高效(走索引)

返回结构设计

{
  "posts": [...],
  "next_cursor": "cursor_string",
  "has_more": true
}

1️⃣ posts
和 Feed 一样,一般会包含:

  • 内容
  • 媒体
  • 计数(likes/comments)
  • 用户信息(有时可以省略)

👉 但这里有个细节:
user 信息其实是冗余的

因为:

已经知道 user_id 了

但仍可能保留:

  • 避免前端多处理
  • 保持接口结构一致(和 Feed 统一)

2️⃣ next_cursor

  • 用于下一页请求
  • 通常是最后一条数据的标记

3️⃣ has_more

  • 避免客户端多发请求
  • 提升体验

后端实现

1️⃣ 数据模型

posts 表(或分库分表)
字段:
- post_id(主键 / 排序 key)
- user_id(索引)
- created_at

2️⃣ 查询路径
👉 直接查 Post 表
不需要:

  • ❌ Feed 表
  • ❌ 推荐系统
  • ❌ 粉丝关系

3️⃣ 索引设计(重点)
必须有联合索引:

(user_id, post_id DESC)

或:

(user_id, created_at DESC)

👉 否则会慢

4️⃣ 是否需要缓存?
视情况而定:
✅ 热点用户(大 V)

  • 可以缓存前几页

❌ 普通用户

  • 直接查数据库即可

权限与扩展点

这个接口虽然简单,但有一些隐含设计点:
1️⃣ 是否需要登录?
这里没写 Authorization,但现实中:

  • 查看公开用户:❌ 不需要登录
  • 查看私密内容:✅ 需要权限

2️⃣ 是否包含草稿 / 私密微博?
可能需要区分:

viewer_id == user_id

👉 才能看到:

  • 草稿
  • 仅自己可见内容

3️⃣ 是否支持置顶微博?
常见需求:

  • 置顶内容要插在最前面

👉 处理方式:

  • 单独查一条
  • 再 merge 到结果

👉 这个接口本质是:
基于 (user_id + cursor) 的顺序分页查询,是 Feed 系统中最基础、最稳定、最容易扩展的一层

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐