2

接口分类

  1. 增删改查接口
  2. 业务接口

增删改查接口

主要负责对数据库数据进行增删改查,用户管理,商品管理,订单管理等,主要为后台管理系统接口和配置接口,严格按照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()

部署

  1. nginx
  2. gunicorn app:app -k "egg:meinheld#gunicorn_worker" -w 9

目录结构

  • app.py,入口
  • actions/ action目录
  • resources/ resouce目录
  • .gitignore

文件上传

特殊接口,form-data格式,用户直接上传到对象存储服务器,使用对象存储服务器生成一次性上传token,返回文件id。

文件获取:根据文件id从对象存储服务器获取临时下载地址。

用户认证

token附在header中,保证日志的干净

编码表

所有下拉框类型,枚举类型,都统一存储至统一的编码表中。


已注销
981 声望48 粉丝

Focus on programming efficiency