【山竹记账后端】RESTful API 是什么
大纲链接 §
[toc]
1. REST风格是什么 ⇧
REST是什么?
Representational State Transfer- 一种网络软件 架构风格
- 不是标准、不是协议、不是接口,只是一种风格
- Roy于2000年在自己博士论文中提到此术语
- Roy曾参与撰写HTTP规格文档
怎么做?
- 以资源为中心,一旦此为名字一般就是资源,如果为动词就不是资源:用户、创建用户
- 充分利用 HTTP现有功能,如动词、状态码、头部字段
- Github API 就比较符合
REST
参考
REST风格举例
请求1:创建 item
|
|
- 注意货币的最小单位,避免浮点数的精度问题,
99分
请求2:创建 item
|
|
请求3:更新 item
|
|
反风格:
|
|
- 反方观点:全用 POST 多省事儿
- 我方观点:自己想路径,多费事儿
请求4:删除 item
|
|
反风格:
|
|
- 反方观点:POST 多省事儿
- 我方观点:有 DELETE 不用非要自己想,多费事儿
请求5:获取 一个或多个 item
|
|
- 单条或多条记录
- 单条
GET /api/v1/items/1省略了id - 多条
GET /api/v1/items?page=1&per_page=10获取分页数据 - 按用户获取通过传
id获取多条GET /api/v1/user/2/items?...从属关系,资源嵌套 - 无资源嵌套,拍平
GET /api/v1/items?user_id=2
- 单条
- 数组
- 属于两个tag的记录
GET /api/v1/items?tags_id[]=1&tag_id[]=2 - 表示资源数组
tags_id[],后端框架自动拼接,比如rails - 其他框架的反风格:
GET /api/v1/items?tags_id=1,2 - 如果
url太长就不得不改为POST
- 属于两个tag的记录
- 排序,二重排序
GET /api/v1/items?sort_by[]=id+asc&sort_by[]=name+desc+就是空格- 排序条件相同则按创建时间排序
- 搜索
GET /api/v1/items?keyword=hi- 反风格
GET /api/v1/items/search/hi
REST风格总结 ⇧
- 尽量以资源为中心:
url里的items就是资源 - 尽量使用
HTTP现有功能:其实响应头里也可以包含内容,但目前的例子都没有用到 - 可以适当违反规则:比如
/api/v1/items/search/hi
人话版REST风格总结 ⇧
- 看见 路径 就知道请求什么东西
- 看见 动词 就知道是什么操作
- 看见 状态码 就知道结果是什么
200- 成功201- 创建成功400- 其他所有错误,详细原因可以放在body里404- 未找到403- 没有权限401- 未登录422- 无法处理的实体,参数有问题402- 需付费412- 不满足前提条件,流程中常用429- 请求太频繁
为什么不喜欢REST ⇧
需求:批量创建
items
POST /api/v1/items只能创建一个item返回一个结果
可以适当改造
REST
POST /api/v1/items/batch- 请求消息体
[{"amount": 1}, {"amount": -2}, {"amount": 3}] - 响应内容
{"resources: [{...}, null, {...}]"}, {"errors": [null, {...}, null]} - 更多批处理
POST /api/v1/items/batchDELETE /api/v1/items/batchUPDATE /api/v1/items/batch
符合
REST风格的API就叫RESTful API
2. API概要设计 ⇧
- 使用
Rails提供的强大工具
2.1 发送验证码 ⇧
- 资源:
validation_codes - 动作: 只有一个
createPOST - 状态码:
200 | 201 | 422 | 429即成功 | 创建成功 | 请求参数验证错误 | 请求太频繁
2.2 登入登出 ⇧
- 资源:
session(注意没有s,单点登录) - 动作:
create | destroyPOST | DELETE - 状态码:
200 | 422
2.3 当前用户 ⇧
- 资源:
me - 动作:
showGET - 状态码:
200 | 429
2.4 记账数据 ⇧
- 资源:
items - 动作:
create | update | show | index | destroyupdate对应PATCH表示部分字段更新show对应GET /items/:id用来表示一条记账记录index对应GET /items?since=2026-01-01&before=2026-02-01destroy对应DELETE表示删除,一般为软删除
- 状态码:
200 | 201 | 422 | 429
2.5 标签 ⇧
- 资源:
tags - 动作:
create | update | show | index | destroy - 状态码:
200 | 201 | 422 | 429
2.6 打标签* 暂不实现 ⇧
记录用户和标签的关系
- 资源:
taggings(动词的名词形式) - 动作:
create | index | destroy - 状态码:
200 | 201 | 422 | 429
API概要设计已完成
- 接下来有一些细节要注意
3. 开始实现-路由 api ⇧
手动添加路由 config/routes.rb ⇧
|
|
对比使用 namespaces 简略写路径,自动生成路由 ⇧
|
|
namespace自动添加前缀(命名空间)- 运行命令
bin/rails routes查看路由:URI Pattern对应Controller#ActionGET /api/v1/validation_codes(.:format)对应api/v1/validation_codes#indexPOST /api/v1/validation_codes(.:format)对应api/v1/validation_codes#createGET /api/v1/validation_codes/:id(.:format)对应api/v1/validation_codes#showPATCH /api/v1/validation_codes/:id(.:format)对应api/v1/validation_codes#updateDELETE /api/v1/validation_codes/:id(.:format)对应api/v1/validation_codes#destroy
resources :xxx自动生成资源对应的6个方法- 手动实现这些
api对应的方法
配置路由缺省方法 ⇧
|
|
resources :validation_codes, only: [:create]仅生成配置的路由、方法
配置好其他所有路由 ⇧
|
|
具体对应方法实现先暂时不写
参考文档
3. 实现 validation_codes 的 create 的路由 ⇧
创建数据表 ⇧
创建表
运行命令
bin/rails g model ValidationCode email:string kind:integer used_at:datetime注意
ValidationCode没有s1 2 3 4 5bin/rails g model ValidationCode email:string kind:integer used_at:datetime # invoke active_record # create db/migrate/20260909153656_create_validation_codes.rb # create app/models/validation_code.rb
db/migrate/20260909153656_create_validation_codes.rb修改部分配置
|
|
迁移数据库 ⇧
运行命令
bin/rails db:migrate1 2 3 4== 20260909153656 CreateValidationCodes: migrating ============================ -- create_table(:validation_codes) -> 0.0273s == 20260909153656 CreateValidationCodes: migrated (0.0274s) ===================
反悔迁移数据库 ⇧
由于
validation_codes的code字段未添加,需要撤销迁移
运行命令
bin/rails db:rollback撤销迁移1 2 3 4== 20260909153656 CreateValidationCodes: reverting ============================ -- drop_table(:validation_codes) -> 0.0048s == 20260909153656 CreateValidationCodes: reverted (0.0082s) ===================
再次修改
db/migrate/20260909153656_create_validation_codes.rb
|
|
再次运行
bin/rails db:migrate1 2 3 4== 20260909153656 CreateValidationCodes: migrating ============================ -- create_table(:validation_codes) -> 0.0135s == 20260909153656 CreateValidationCodes: migrated (0.0136s) ===================
创建 Controller ⇧
运行命令
bin/rails g controller validation_codes create1 2create app/controllers/validation_codes_controller.rb route get "validation_codes/create"删除自动添加生成的路由
修改前缀 添加目录 api/v1 ⇧
- 在
app/controllers中添加目录api/v1 - 将生成的
validation_codes_controller.rb移到app/controllers/api/v1目录下 修改
validation_codes_controller.rb中类名,添加命名空间前缀Api::V1::ValidationCodesController注意命名空间需要添加两个冒号隔开
Api::V1::1 2 3 4 5class Api::V1::ValidationCodesController < ApplicationController def create head 201 end end
启动服务
bin/rails s查看是否可以访问到
/api/v1/validation_codes- 使用命令
curl -X POST http://127.0.0.1:3000/api/v1/validation_codes -v -v查看返回结果中状态码1< HTTP/1.1 201 Created
- 使用命令
修改
head 202再运行curl -X POST http://127.0.0.1:3000/api/v1/validation_codes -v查看返回结果中状态码
5. 实现 items 的分页 ⇧
实现分页的两种方案
- 使用
page和per_page参数,见kaminari或pagy库 - 使用
start_id和limit参数,需要id是自增数字
创建 Items 的 Controller ⇧
运行命令
bin/rails g controller Api::V1::Items index create1 2 3 4 5 6 7create app/controllers/api/v1/items_controller.rb route namespace :api do namespace :v1 do get "items/index" post "items/create" end end删除自动生成的路由
6. $3 ⇧
7. $3 ⇧
8. $3 ⇧
参考文章
相关文章
- 无
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名