feat: improve rest api middleware
This commit is contained in:
parent
5847c9eeab
commit
edbe1ecb67
@ -152,32 +152,6 @@ describe('koa middleware', () => {
|
||||
expect(response.body.arr).toEqual([3, 4]);
|
||||
});
|
||||
|
||||
it('shound work', async () => {
|
||||
const app = new Koa();
|
||||
const resourcer = new Resourcer();
|
||||
const agent = supertest.agent(app.callback());
|
||||
|
||||
resourcer.define({
|
||||
name: 'tables#fields',
|
||||
actions: {
|
||||
async list(ctx, next) {
|
||||
ctx.body = ctx.body || {};
|
||||
ctx.body.arr = ctx.body.arr || [];
|
||||
ctx.body.arr.push(3);
|
||||
await next();
|
||||
ctx.body.arr.push(4);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
app.use(resourcer.middleware({
|
||||
nameRule: ({ resourceName, associatedName }) => associatedName ? `${associatedName}#${resourceName}` : resourceName,
|
||||
}));
|
||||
|
||||
const response = await agent.get('/tables/demos/fields');
|
||||
expect(response.body.arr).toEqual([3, 4]);
|
||||
});
|
||||
|
||||
describe('action options', () => {
|
||||
let resourcer: Resourcer;
|
||||
let app: Koa;
|
||||
|
@ -29,11 +29,51 @@ export interface KoaMiddlewareOptions {
|
||||
nameRule?: (params: ParsedParams) => string;
|
||||
|
||||
/**
|
||||
* 上下文中的 key - ctx[paramsKey]
|
||||
* 自定义 action name
|
||||
*
|
||||
* 可以单独配置 paramsKey,默认为 params
|
||||
* 默认为
|
||||
*
|
||||
* - list 查看列表
|
||||
* - create 新增数据
|
||||
* - get 查看数据详情
|
||||
* - update 更新数据
|
||||
* - delete 删除数据
|
||||
*/
|
||||
paramsKey?: string;
|
||||
accessors?: {
|
||||
|
||||
/**
|
||||
* 查看列表
|
||||
*/
|
||||
list?: string;
|
||||
|
||||
/**
|
||||
* 新增数据
|
||||
*/
|
||||
create?: string;
|
||||
|
||||
/**
|
||||
* 查看数据详情
|
||||
*/
|
||||
get?: string;
|
||||
|
||||
/**
|
||||
* 更新数据
|
||||
*/
|
||||
update?: string;
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
delete?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ResourcerOptions {
|
||||
|
||||
/**
|
||||
* 前缀
|
||||
*/
|
||||
prefix?: string;
|
||||
|
||||
/**
|
||||
* 自定义 action name
|
||||
@ -127,10 +167,14 @@ export class Resourcer {
|
||||
|
||||
protected middlewareHandlers = new Map<string, any>();
|
||||
|
||||
protected paramsKey = 'params';
|
||||
|
||||
protected middlewares = [];
|
||||
|
||||
public readonly options: ResourcerOptions;
|
||||
|
||||
constructor(options: ResourcerOptions = {}) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入指定目录下的 resource 配置(配置的文件驱动)
|
||||
*
|
||||
@ -174,6 +218,14 @@ export class Resourcer {
|
||||
return this.resources.has(name);
|
||||
}
|
||||
|
||||
registerAction(name: ActionName, handler: HandlerType) {
|
||||
this.registerActionHandler(name, handler);
|
||||
}
|
||||
|
||||
registerActions(handlers: Handlers) {
|
||||
this.registerActionHandlers(handlers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册全局的 action handlers
|
||||
*
|
||||
@ -212,10 +264,6 @@ export class Resourcer {
|
||||
return this.getResource(name).getAction(action);
|
||||
}
|
||||
|
||||
getParamsKey() {
|
||||
return this.paramsKey;
|
||||
}
|
||||
|
||||
getMiddlewares() {
|
||||
return this.middlewares;
|
||||
}
|
||||
@ -228,48 +276,40 @@ export class Resourcer {
|
||||
}
|
||||
}
|
||||
|
||||
middleware(options: KoaMiddlewareOptions = {}) {
|
||||
const { prefix, accessors, paramsKey = 'params', nameRule = getNameByParams } = options;
|
||||
return async (ctx: ResourcerContext, next: () => Promise<any>) => {
|
||||
restApiMiddleware(options: KoaMiddlewareOptions = {}) {
|
||||
const { prefix, accessors } = options;
|
||||
const restApiMiddleware = async (ctx: ResourcerContext, next: () => Promise<any>) => {
|
||||
ctx.resourcer = this;
|
||||
let params = parseRequest({
|
||||
path: ctx.request.path,
|
||||
method: ctx.request.method,
|
||||
}, {
|
||||
prefix,
|
||||
accessors,
|
||||
prefix: this.options.prefix || prefix,
|
||||
accessors: this.options.accessors || accessors,
|
||||
});
|
||||
if (!params) {
|
||||
return next();
|
||||
}
|
||||
try {
|
||||
const resource = this.getResource(nameRule(params));
|
||||
const resource = this.getResource(getNameByParams(params));
|
||||
// 为关系资源时,暂时需要再执行一遍 parseRequest
|
||||
if (resource.options.type !== 'single') {
|
||||
if (resource.options.type && resource.options.type !== 'single') {
|
||||
params = parseRequest({
|
||||
path: ctx.request.path,
|
||||
method: ctx.request.method,
|
||||
type: resource.options.type,
|
||||
}, {
|
||||
prefix,
|
||||
accessors,
|
||||
prefix: this.options.prefix || prefix,
|
||||
accessors: this.options.accessors || accessors,
|
||||
});
|
||||
if (!params) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
// action 需要 clone 之后再赋给 ctx
|
||||
ctx.action = this.getAction(nameRule(params), params.actionName).clone();
|
||||
ctx.action = this.getAction(getNameByParams(params), params.actionName).clone();
|
||||
ctx.action.setContext(ctx);
|
||||
const query = parseQuery(ctx.request.querystring);
|
||||
// 兼容 ctx.params 的处理,之后的版本里会去掉
|
||||
ctx[paramsKey] = {
|
||||
table: params.resourceName,
|
||||
tableKey: params.resourceKey,
|
||||
relatedTable: params.associatedName,
|
||||
relatedKey: params.resourceKey,
|
||||
action: params.actionName,
|
||||
};
|
||||
if (pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\::actionName}').test(ctx.request.path)) {
|
||||
await ctx.action.mergeParams({
|
||||
...query,
|
||||
@ -287,7 +327,12 @@ export class Resourcer {
|
||||
} catch (error) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
};
|
||||
return restApiMiddleware;
|
||||
}
|
||||
|
||||
middleware(options: KoaMiddlewareOptions = {}) {
|
||||
return this.restApiMiddleware(options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user