目录
0.基础概念
1.新鲜事–消息流的实现方式
2.用户系统(1)–缓存
2.用户系统(2)–好友关系
问题:设计消息流相关的API
0.参考
一个经典问题,当访问一个URL的时候发生了什么?
简单列举一些步骤。
更多详细的内容可以参考, 键入网址到网页显示,期间发生了什么?
- 浏览器输入URL
- 访问最近的DNS服务器,查询对应域名的IP地址
- 向该IP地址发送请求
- 服务器接受到请求由HttpServer转发给Web应用进行处理
- Web应用根据对应路径和逻辑处理请求,并返回给用户
RESTful API
参考内容:RESTful API
简单来说,REST是一种基于资源的架构风格,所有的能够命名的对象都可以是资源,如User,Order…,RESTful API就是遵循REST风格约束的API。实际工程中很难满足全部约束条件,根据具体情况适当调整。
1.明确设计需求
首先列举一些需要的功能:
- 获取新鲜事列表
- 翻页
- API返回的内容格式
2.翻页
翻页一般有两种处理方式,
第一种是比较传统的使用pageId
作为参数
GET /api/newsfeeds/?page=1
这种方式的好处是可以直接跳转到你想要的页数。
缺点是如果有新数据插入的时候,翻到下一页可能会看到上一页刚看过的内容。
很显然这种不适合用在新鲜事系统中。
新鲜事一般不会使用页码翻页,而是使用无限翻页
GET /api/newsfeeds/?max_id=1000
假设每页有20个内容
- 如果请求中没有
max_id
,就表示第一页,返回最新的20条内容 - 如果有
max_id
就从id <= max_id
的内容中找到最新的20条返回
怎么判断有没有下一页
最简单的方法是判断返回的结果是否为空。这样的缺点是划到最后一页时会多一次请求,一个优化方法时每次请求的时候多取一个数据,伪代码如下:
返回数据的格式
{
"next_max_id": xxxx,
"contents": [xxxx]
}
count = 20
if 没有 max_id
获取最新的20 + 1条数据
else
获取id <= max_id的最新的20 + 1条数据
if 获取到的数据数量等于20 + 1条
next_max_id等于第20 + 1条数据的id
else
next_max_id设为空
怎么下拉获取更新内容
使用min_id
,找到所有id > min_id
的所有内容
GET /api/newsfeeds/?mid_id=<id>
3.返回的内容格式
API的返回格式一般分为结构化数据和HTML等等,结构化数据一般用JSON和XML,但是目前主要还是以JSON为主
返回的文本内容里面有@某个人的链接,怎么处理
Hello, <a href="/users/123/">@xxx</a>!
一般想到的是直接返回html,但是这样会有几个缺点
- js注入攻击,这种现在已经很少出现了
- 并不是所有的客户端都可以支持
<a></a>
显示链接 - 最重要的就是,一旦链接内容存入数据库,后面链接发生变化很难去做修改。比如从
/users/<id>
改成/users/<name>
,基本不可能遍历数据库去进行修改。
推荐做法是自定义链接结构,让不同的客户端自行解析,比如
<user username="xxx">Hello</user>
如果需要修改结构,只需要对应的客户端修改对应的逻辑即可。