基础框架
OVERVIEW
集成标准化的请求处理流程,参数校验,输出校验,错误处理,输出格式,日志格式等。
Base View
指定请求方法
method
可选
# 示例:
from guanmai.framework.views import CommonBaseView
class SampleView(CommonBaseView):
method = 'POST'
输入参数校验
param_schema
基于jsonschema开发,语法和规则都大体遵守json schema规范。详细的规范可以参考以下链接:
https://json-schema.org/understanding-json-schema/basics.html
# 示例:
from guanmai.framework.views import CommonBaseView
from guanmai.framework import schemas
class SampleView(CommonBaseView):
param_schema = {
'type': 'object',
'properties': {
'name': {'type': 'string', 'maxLength': 16},
'phone': {'type': 'string', 'pattern': r'\d{11}'},
'permission': {
'type': 'array',
'items': {
'type': 'string',
'enum': ['get_order', 'edit_order', 'remove_order']
}
}
}
}
class Sample2View(CommonBaseView):
param_schema = schemas.ObjectSchema({
'name': schemas.StringSchema(maxLength=16),
'phone': schemas.StringSchema(pattern=r'\d{11}'),
'permission': schemas.ArraySchema(items=schemas.StringSchema(
enum=['get_order', 'edit_order', 'remove_order']
)),
})
# 此为Sample2的shortcut实现
class Sample3View(CommonBaseView):
param_schema = {
'name': schemas.StringSchema(maxLength=16),
'phone': schemas.StringSchema(pattern=r'\d{11}'),
'permission': schemas.ArraySchema(items=schemas.StringSchema(
enum=['get_order', 'edit_order', 'remove_order']
)),
}
reference
StringSchema
IntSchema
FloatSchema
BoolSchema
ArraySchema
ObjectSchema
扩展
required
required关键字在jsonschema中表示object类型必传的properties,例如:
{
"type": "object",
"required": ["a", "b"]
}
而为了更适应“参数校验”的写法,改为如下写法:
schemas.ObjectSchema({
'name': schemas.StringSchema(required=False)
})
alias
为了兼容老接口的字段,设置别名属性,该属性仅在ObjectSchema下有效,用法如下:
class Sample3View(CommonBaseView):
param_schema = schemas.ObjectSchema({
'name': schemas.StringSchema(alias=['username', 'user_name'], maxLength=16),
})
别名规则如下:
- 优先匹配正式的参数名,如果别名跟其他参数名冲突,别名会被忽略
- 同一个object下的别名不能重复
DatetimeSchema
jsonschema不支持日期时间类型,string类型的format字段没有被大部分语言实现,因此新增了该类型。
from datetime import datetime
class SampleView(CommonBaseView):
param_schema = schemas.ObjectSchema({
'birthday': schemas.DatetimeSchema(
minimum=datetime(2018, 1, 1),
maximum=datetime(2018, 1, 1)
),
})
日期类型检验规则
datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
DateSchema
from datetime import date
class SampleView(CommonBaseView):
param_schema = schemas.ObjectSchema({
'birthday': schemas.DateSchema(
minimum=date(2018, 1, 1),
maximum=date(2018, 1, 1)
),
})
日期类型检验规则
string like "2018-01-01"
输出参数校验
output_schema
用法参考param_schema
class SampleView(CommonBaseView):
output_schema = schemas.ObjectSchema({
'name': schemas.StringSchema(maxLength=16),
'phone': schemas.StringSchema(pattern=r'\d{11}'),
'permission': schemas.ArraySchema(items=schemas.StringSchema(
enum=['get_order', 'edit_order', 'remove_order']
)),
})
内置变量
request
django HttpRequest对象
params
格式化后的输入参数,FrozenDict对象,不可变
内置方法
check_params
处理param_schema以外的校验逻辑,返回值会被传递到process方法
process
核心的业务逻辑,返回值会被传递到output方法
output
处理返回
非HttpResponse的返回会被放到
from guanmai.framework.views import CommonBaseView
from guanmai.framework import schemas
from guanmai.framework.errors import InvalidParamError
from user_app.models import User
from order_app.models import Order
class CreateOrderView(CommonBaseView):
param_schema = {
'phone': schemas.StringSchema(),
'sku_id': schemas.StringSchema(),
'count': schemas.IntSchema(minimum=0)
}
output_schema = {
'id': schemas.IntSchema()
}
def check_params(self):
try:
user = User.objects.get(phone=phone)
sku = Sku.objects.get(id=self.params['sku_id'])
except:
raise InvalidParamError()
return user, sku
def process(self, user, sku):
order = Order.objects.create(
user_id=user.id, sku_id=self.params['sku_id'], count=self.params['count']
)
return order
def output(self, order):
return {'id': order.id}
initial
初始化
Note:由于在__init__出了错无法打印出请求的完整日志,推荐所有具体的初始化行为都放在initial方法,__init__只做简单的变量声明
on_request
该方法在check_params之前会被调用
on_response
该方法在output之后被调用
错误码
# 1000 ~ 2999为保留号段
SYSTEM_ERROR = 1001
AUTH_ERROR = 1002
PERMISSION_DENY = 1003
PARAM_ERROR = 1004
NOT_ALLOW = 1005
OUTPUT_ERROR = 1006
HTTP_REDIRECT = 1010
DB_ERROR = 1020
MYSQL_ERROR = 1021
MONGO_ERROR = 1022
REDIS_ERROR = 1023
PAY_ERROR = 1110
# 3000以后的为自定义码段,允许重复定义
SELF_DEFINE = 3000