# REST API 服务接口开发规范

# 目录规范

├── app               # 业务代码
│   ├── api           RestApi
│   │   ├── cms       /cms      CMS接口
│   │   ├── v1        /api/v1   v1版api接口
│   │   ├── v2        /api/v2   v2版api接口
│   │   └── apijson   /apijson  统一api接口
│   │
│   ├── extensions    扩展库
│   │
│   ├── lib           Lib库
│   │
│   ├── models        Model库
│   │
│   └── services      Service库
│
├── assets            # 静态资源
│
├── config            # 配置文件
│
├── core              # 平台核心库
│
└── app.js            # 主入口

# Model 规范

模型以大写字母开头

const { User, Product } = require('../models')

只涉及本模型(集合、表)内数据处理的方法都放到模型内,以静态方法实现

userSchema.statics = {
  async login(username, password) {
    ...
  },
  ...
}

# Service 规范

服务以大写字母开头

const { UserToken, ProductService } = require('../services')

与多个模型(集合、表)数据相关处理的方法都放到服务内,以对象定义,静态方法或实例方法实现

class MpService {
  constructor({ appId, secret, ...conf }) {
    this.appId = appId
    this.secret = secret
    this.conf = conf
  }
  /**
   * 从缓存中取accessToken,如没有则从微信取并存入缓存
   * @param {string} appId
   * @param {string} secret
   */
  static async getAccessToken(appId, secret) {
    let res = await cache.get(appId)
    if (res) return res
    const { accessToken, expiresIn } = await getAccessToken(appId, secret)
    await cache.set(appId, accessToken, expiresIn)
    return accessToken
  }
}

# Lib 规范

  1. 保存 lib/ 目录下
  2. 与业务无关

# URL 规范

  1. 全小写
  2. '-'联接
/api/v1/spu/by-id
/api/v1/user/id/:id   // 通过id取user数据
/api/v1/user/page     // 通过分页取 user列表

# API 数据结构规范

# 设计原则

  1. 尽可能一次请求满足前端数据需求

# Method

HTTP Method CRUD
GET
POST 新增
PUT 更新
DELETE 删除

# UnifyResponse

  1. 统一 JSON 格式
  2. 更新数据的 api,不返回新记录数据,返回:
result = {
  code, // 0 成功
  message,
  request // 'POST /api/v1/spu'
}

# 异常格式及编码意义

  1. code:

    code 状态
    0-9998 正常
    9999 未知服务器异常
    10000+ 业务异常
  2. Http 状态码:

    statusCode 状态
    200 成功
    201 创建成功
    401 未登录
    403 未授权
    404 未找到
    500 服务器异常

# 分页格式

  1. 返回数据格式
result = {
  total,
  page, // 1 开始
  pageSize, // count
  totalPage, // 可以不返回
  items // []
}
  1. 请求数据格式:
{
  page: 1,  // 第几页,开始页1
  pageSize: 15, // 每页记录数,默认15
}

# 空数据 返回格式

  1. 单体对象 如 spu
// statusCode:404 + UnifyResponse
result = {
  code: 60001,
  message: 'spu未找到',
  request: 'GET /api/v1/spu'
}
  1. 不分页 数组
// statusCode:200 + []
result = []
  1. 分页
// statusCode:200 +
result = {
  total: 0,
  items: [],
  // 下面可省略
  page,
  pageSize,
  totalPage
}