RESTful API具体是什么样子的
- 基本的URI如 http://github.com/user
- 标准的HTTP方法
- 传输的数据媒体类型,如JSON,XML
请求设计规范
- URI使用名词,尽量用复数,如/users
- URL使用嵌套表示关联关系,如/users/12/repos/5
- 使用正确的HTTP方法,如GET/POST/PUT/DELETE
- 不符合CRUD的情况:POST/action/子资源
响应设计规范
- 查询
- 分页
- 字段过滤
- 状态码
- 错误处理
安全
- HTTPS
- 鉴权
- 限流
HTTP OPTIONS方法
- 检测服务器所支持的请求方法
- CORS中的预检请求
allowedMethods
方法
- 响应
options
方法,告诉它所支持的请求方法 - 相应地返回
405
(不允许,还没写,可以实现)和501
(没实现,服务端没法实现)
app.use(userRouter.allowedMethods())
RESTful API最佳实践——增删改查应该返回什么响应
204 No Content
成功,但是没有返回内容
控制器简介
- 拿到路由分配的任务,并执行
- 在Koa中是一个中间件
为什么要用控制器
获取HTTP请求参数
Query String
,如q?=keyword
(可选)Router Params
,如/users/:id
(必选)Body
请求体,如{name: "李雷"}
Header
,如Accept、Cookie
处理业务逻辑
发送HTTP响应
- 发送
Status
,如200/400
等 - 发送
Body
,如{name: "李雷"}
- 发送
Header
,如Allow、Content-Type
编写控制器的最佳实践
- 每个资源的控制器放在不同的文件里
- 尽量使用类+类方法的形式编写控制器
- 严谨的错误处理
获取HTTP请求参数
学习断点调试
获取query
ctx.query
获取router params
- 路由为
/user/:id
时,使用ctx.params.id
来获取路由参数。
获取body
ctx.request.body
获取header
###异常状况的种类
- 运行时错误,都返回500
- 逻辑错误,如找不到返回404、先决条件失败(412)、无法处理的实体(参数格式不对,422)等
Session简介
session的优势
- 相比
JWT
,最大的优势就在于可以主动清除session
了。 session
保存在服务器端,相对比较安全。- 结合
cookie
使用,较为灵活,兼容性较好。
session的劣势
cookie
+session
在跨域场景表现并不好。- 如果是分布式部署,需要做多机共享
session
机制。 - 基于
cookie
的机制很容易被CSRF
。 - 查询
session
信息可能会有数据库查询操作。
session相关的概念介绍
session
:主要存放在服务器端,相对安全。cookie
:主要存放在客户端,并且不是很安全。sessionStorage
:仅在当前回话下有效,关闭页面或浏览器后被清除。localStorage
:除非被清除,否则永久保存。
JWT简介
什么是JWT
JSON Web Token
是一个开放标准(RFC 7519
)。- 定义了一种紧凑且独立的方式,可以将各方之间的信息作为
JSON
对象进行安全传输。 - 该信息可以验证和信任,因为是经过数字签名的。
JWT的构成
- 头部(
Header
)typ
:token
的类型,这里固定JWT
。alg
:使用的hash
算法,例如:HMAC SHA256
或者RSA
。
- 有效载荷(
Payload
)- 存储需要传递的信息,如用户
ID
用户名等。 - 还包含元数据,如过期时间、发布人。
- 与
Header
不同,Payload
可以加密。
- 存储需要传递的信息,如用户
- 签名(
Signature
)- 对
Header
和Payload
部分进行签名。 - 保证
Token
在传输的过程中没有被篡改。
- 对
JWT对比Session
- 可拓展性。
JWT
优于Session
- 安全性。
- RESTful API。
JWT
属于无状态所以使用JWT
。 - 性能。可能有大量用户信息,影响每一个
http
请求。 - 时效性。
JWT
只能过期之后才能失效,而session
能在服务端进行失效处理。
上传图片需求分析
图片种类
- 用户头像
- 封面图片
- 问题和回答中的图片
- 话题图片
- 其它
功能
- 基础功能:上传图片,生成图片链接
- 附加功能:限制上传图片的大小与类型、生成高中低三种分辨率的图片链接、生成
CDN
用户个人资料Schema设计
- 性别
// enum 表示可枚举
gender: { type: String, enum: ['male', 'female'], default: 'male', required: true }
- 地区
location: { type: [type: String] } // 这样表示字符串数组