接口分类
- 增删改查接口
- 业务接口
增删改查接口
主要负责对数据库数据进行增删改查,用户管理,商品管理,订单管理等,主要为后台管理系统接口和配置接口,严格按照RESTful规范编写, 状态码按照标准规范。
入口 /api/resouces/{orders, users等}
日志内容: 时间,ip, 请求方式,请求路径,用户信息,操作类型,操作结果,ua
业务接口
业务主流程接口抽象,登录,注册,修改密码,下单,付款,确认收货等,主要是终端用户的操作主流程的接口,规范按照自定义更佳, 返回错误需要明确每个错误的业务错误码。只要正确收到和返回请求,HTTP状态码就为200 OK
,包括服务器内部错误。未知错误使用code=-1。尽量不要将任何不可控的错误以及调用栈暴露,而应当在捕获到异常后,将调用栈打印到日志中。
入口
POST
/api/action
参数
{
"action": "login",
"data": {
"phone":"111",
"password": "123456"
}
}
日志内容
时间,ip,请求方式,请求路径,用户标识,错误码,错误内容, action,data,设备ua等信息
返回
{
"code": 10000,
"msg": "用户未注册",
"data": null
}
实现
框架:
import traceback
class ErrorCode:
sys_unknown = "未知错误", -1
sys_action_not_exist = "操作不存在", 10000
sys_params_wrong = "参数错误", 10001
already_register = "用户已注册", 10002
verify_code_wrong = "验证码错误", 10003
action_not_exist = "操作不存在", 10004
class Action:
schema = {}
def __init__(self, data):
assert data, ErrorCode.sys_params_wrong
self.data = data
def run(self, data):
raise NotImplementedError()
class App:
action_map = {}
def dispatch(self, data):
try:
assert data["action"] in self.action_map, ErrorCode.sys_action_not_exist
action = self.action_map[data["action"]]
return {
"code": 0,
"msg": "",
"data": action.run(data["params"])
}
except AssertionError as e:
msg, code = e
return {
"code": code,
"msg": msg,
"data": None
}
except Exception:
traceback.print_exc()
msg, code = ErrorCode.sys_unknown
return {
"code": code,
"msg": msg,
"data": None
}
注册:
from schema import And, Schema
from acts import Action, App, ErrorCode
class MyErrorCode(ErrorCode):
params_wrong = "参数错误", 10000
already_register = "用户已注册", 10001
verify_code_wrong = "验证码错误", 10002
action_not_exist = "操作不存在", 10003
unknown = "未知错误", -1
class RegisterAction(Action):
schema = Schema({
"verify_code": And(str, len),
"phone": And(str, len),
"password": And(str, len)
})
auth = False
def run(self, data):
assert check_verify_code(data["verify_code"]), MyErrorCode.verify_code_wrong
assert User.get(data["phone"]), MyErrorCode.already_register
return {"token": "token"}
action_map = {
'register': RegisterAction
}
class MyApp(App):
action_map = action_map
app = MyApp()
部署
nginx
gunicorn app:app -k "egg:meinheld#gunicorn_worker" -w 9
目录结构
- app.py,入口
- actions/ action目录
- resources/ resouce目录
- .gitignore
文件上传
特殊接口,form-data格式,用户直接上传到对象存储服务器,使用对象存储服务器生成一次性上传token,返回文件id。
文件获取:根据文件id从对象存储服务器获取临时下载地址。
用户认证
token附在header中,保证日志的干净
编码表
所有下拉框类型,枚举类型,都统一存储至统一的编码表中。