API规范

下面以账号表为例,介绍相关api命名、参数、返回值等编写规范。

1、账号详情

接口名称: get
功能说明: 获取某个账号详情
请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
_id ObjectId Y 账号ID

api result schema:account_detail

account_detail:
  strict_mode: true
  model_name: account
  meta: object_result
  data:
    _id:
      type: 'object_id'
      example: '5da57976ce6d2a647d539af0'
      note: 'id'
    name:
      type: 'string'
      example: '张三'
      note: '用户名称'
    group_info:
      type: 'object_ref'
      schema: group_brief

返回结果:

{
    "_id":"5a72897dce6d2a27056b219f",
    "name":"憨憨",
    "group_info": {
         "_id": "5a72897dce6d2a27056b219g",
         "name": "后端组"
    },
}

代码示例:

@api_result('account_detail')
def get(self, params, **kwargs):
    _id = param_convert.object_id_param('_id', params)
    record = api_model_loader.load_account_info(_id)
    return record

2、账号列表

接口名称: find
功能说明: 根据筛选及分页条件获取账号列表
注意事项: 需要考虑根据查询条件构建合适的索引
请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
_meta dict N 分页参数
name string N 名称
state int N 状态

请求示例:

{
    "_meta": {
        "limit": 30,
        "page": 1
    },
    "state": 100
}

api result schema:account_list_item

account_list_item:
  strict_mode: true
  model_name: account
  meta: object_result
  data:
    _id:
      type: 'object_id'
      example: '5da57976ce6d2a647d539af0'
      note: 'id'
    name:
      type: 'string'
      example: '张三'
      note: '用户名称'

返回结果:

{
    "_meta": {
        "has_more": true,
        "page": 1,
        "page_size": 30,
        "result_count": 1148
    },
    "data": [
        {
            "_id": "5a72897dce6d2a27056b219f",
            "name": "憨憨1"
        },
        {
            "_id": "5a72897dce6d2a27056b219e",
            "name": "憨憨2"
        }
    ]
}

代码示例:

@api_result_set_with_meta('account_list_item')
def find(self, params, **kwargs):
    spec = apply_dict_by_rules(params, {
        'name': (
            param_convert.str_param_opt,
        ),
        'state': (
            param_convert.int_param_opt,
        ),
    })
    default_sort = [('_id', -1)]
    return build_result_set_meta(db.Account.find, spec=spec, default_sort=default_sort, params=params)

3、账号创建

接口名称: create
功能说明: 添加新账号
请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
name string Y 名称
phone string Y 手机号
state int Y 状态
group_id object_id N 所属组ID

api result schema:generic_summary

generic_summary:
  strict_mode: true
  meta: object_result
  data:
    _id:
      type: object_id
      example: '5a72897dce6d2a27056b219f'
      note: 对象ID

返回结果:

{
    "_id":"5a72897dce6d2a27056b219f"
}

代码示例:

@api_result('generic_summary')
def create(self, params, **kwargs):
    doc = apply_dict_by_rules(params, {
        'name': (
            param_convert.str_param_opt,
        ),
        'phone': (
            param_convert.str_param_opt,
        ),
        'state': (
            param_convert.int_param_opt,
        ),
        'group_id': (
            param_convert.object_id_param_opt,
        ),
    })
    try:
        biz = AccountBiz.instance()
        record = biz.create_record(doc)
    except RpcRuntimeError as e:
        raise errors.ApiError(zh_message=e.zh_message)
    return record

4、账号编辑

接口名称: update
功能说明: 编辑账号信息
请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
_id object_id Y 名称
name string N 名称
phone string N 手机号
state int N 状态
group_id object_id N 所属组ID

api result schema:generic_summary
返回结果:

{
    "_id":"5a72897dce6d2a27056b219f"
}

代码示例:

@api_result('generic_summary')
def update(self, params, **kwargs):
    record_id = param_convert.object_id_param('_id', params)
    record = api_model_loader.load_account_info(record_id)
    doc = apply_dict_by_rules(params, {
        'name': (
            param_convert.str_param_opt,
        ),
        'phone': (
            param_convert.str_param_opt,
        ),
        'state': (
            param_convert.int_param_opt,
        ),
        'group_id': (
            param_convert.object_id_param_opt,
        ),
    })
    try:
        biz = AccountBiz.instance()
        record = biz.update_record(record, doc)
    except RpcRuntimeError as e:
        raise errors.ApiError(zh_message=e.zh_message)
    return record

5、获取记录详情

接口名称: find_one
功能说明: 获取指定条件的记录详情
场景说明: 通常用于要根据不同纬度来获取一条记录详情,例如通过身份证号或者手机号来定位用户
请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
phone string N 手机号
identity_card_id string N 身份证号

返回结果:

{
    "_id":"5a72897dce6d2a27056b219f",
    "name":"憨憨",
    "group_info": {
         "_id": "5a72897dce6d2a27056b219g",
         "name": "后端组"
    },
}

6、获取全量数据

接口名称: select
功能说明: 不带分页获取所有数据
场景说明: 获取下拉框可选项
注意事项: 只返回需要用到的_id和name字段
请求参数:
返回结果:

{
    "data": [
        {
            "_id": "5a72897dce6d2a27056b219g",
            "name": "后端组"
        },
        {
            "_id": "5a72897dce6d2a27056b219e",
            "name": "产品组"
        }
    ]
}

7、操作类

接口名称: mark_*
功能说明: 操作类标记相关状态
举例说明:

  • 标记完成:mark_done
  • 标记进行中:mark_doing
  • 标记删除:mark_delete
  • 标记取消:mark_cancel
  • 标记关闭:mark_close
  • 打标签:mark_label
  • 标记异常:mark_abnormal

请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
_id object_id Y 主键ID

返回结果:

{
    "ok": true
}

8、批量处理类

接口名称: batch_*
功能说明: 批量操作类
举例说明:

  • 批量添加:batch_add_xxx
  • 批量删除:batch_delete_xxx

请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
_ids list Y 主键ids

返回结果:

{
    "ok": true
}

9、批量操作文档类

接口名称: batch_*
功能说明: 批量添加/编辑
举例说明:

  • 批量创建:batch_create
  • 批量删除:batch_update
  • 批量提交:batch_submit

请求参数:

参数名称: 参数类型: 是否必须: 参数说明:
docs list Y 文档信息列表

请求示例:

{
    "docs": [
        {
            "name": "后端组"
        },
        {
            "name": "产品组"
        }
    ]
}

返回结果:

{
    "ok": true
}

10、支付类

功能说明: 涉及到金额类的操作
举例说明: 充值、提现、转账、收款
特别注意:

  • 接口幂等性
  • 通过一定的策略确保同一单据提供给三方交易系统的单号唯一
  • 通过创建唯一索引来防止重复打款
  • 对于调用第三方交易系统,做成定时任务并使用单进程去执行处理
  • 操作钱包中金额字段时要使用mongodb中原子性的相关操作,例如:inc、pull、$push等

下面以给钱包账号充值为例,我们可以在model中增加如下方法:

def pre_recharge_money(self, money, trans_id):
    """开始充值金额"""
    spec = {
        '_id': self['_id'],
        'pending_transactions': {'$ne': trans_id},
    }
    doc = {
        '$inc': {
            'balance_money': money,
            'frozen_money': money,
        },
        '$push': {
            'pending_transactions': trans_id
        }
    }
    return self.update_doc(spec, doc, check_updated_state=True)

def rollback_recharge_money(self, money, trans_id):
    """回滚充值金额"""
    spec = {
        '_id': self['_id'],
        'pending_transactions': trans_id,
    }
    doc = {
        '$inc': {
            'balance_money': -money,
            'frozen_money': -money,
        },
        '$pull': {
            'pending_transactions': trans_id
        }
    }
    return self.update_doc(spec, doc, check_updated_state=True)

def commit_recharge_money(self, money, trans_id):
    """提交充值金额"""
    spec = {
        '_id': self['_id'],
        'pending_transactions': trans_id,
    }
    doc = {
        '$inc': {
            'frozen_money': -money,
        },
        '$pull': {
            'pending_transactions': trans_id
        }
    }
    return self.update_doc(spec, doc, check_updated_state=True)

注意:针对有些场景api没有定义规范的,需要一起制定完此类情况的开放流程规范后在进行开发。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容