Use generators, send strapi instance in parser and optimizations

This commit is contained in:
Aurélien Georget 2016-01-27 16:45:44 +01:00
parent fad6c2af6d
commit c7049253d6
3 changed files with 91 additions and 61 deletions

View File

@ -19,17 +19,16 @@ module.exports = {
* Parse request * Parse request
*/ */
parse: function (ctx, cb) { parse: function * (ctx, cb) {
switch (ctx.method.toUpperCase()) { switch (ctx.method.toUpperCase()) {
case 'GET': case 'GET':
console.log('GET'); console.log('GET');
break; break;
case 'PUT': case 'PUT':
case 'POST': case 'POST':
this.fetchSchema(ctx, function (err) { yield this.fetchSchema(ctx, function * (err) {
cb(err); yield cb(err);
}); });
console.log('POST|PUT');
break; break;
case 'DELETE': case 'DELETE':
console.log('DELETE'); console.log('DELETE');
@ -42,40 +41,56 @@ module.exports = {
* Fetch attributes schema * Fetch attributes schema
*/ */
fetchSchema : function (ctx, cb) { fetchSchema: function * (ctx, cb) {
const attributes = ctx.request.body; const attributes = ctx.request.body;
if (!attributes.hasOwnProperty('data')) { if (!attributes.hasOwnProperty('data')) {
ctx.response.status = 404; return yield cb({
ctx.response.body = 'Missing `data` member'; status: 403,
body: 'Missing `data` member'
});
} else if (!attributes.data.hasOwnProperty('type')) { } else if (!attributes.data.hasOwnProperty('type')) {
ctx.response.status = 404; return yield cb({
ctx.response.body = 'Missing `type` member'; status: 403,
body: 'Missing `type` member'
});
} else if (!strapi.models.hasOwnProperty(attributes.data.type)) { } else if (!strapi.models.hasOwnProperty(attributes.data.type)) {
ctx.response.status = 404; return yield cb({
ctx.response.body = 'Unknow `type` ' + attributes.data.type; status: 403,
} else { body: 'Unknow `type` ' + attributes.data.type
// Extract required attributes });
const requiredAttributes = _.filter(strapi.models[attributes.data.type].attributes, {required:true});
// Identify required relationships
const relationships = _.indexBy(strapi.models[attributes.data.type].associations, 'alias');
// Extract required relationships
const requiredRelationships = _.intersection(_.keys(requiredAttributes), _.keys(relationships));
console.log(requiredAttributes);
console.log(requiredRelationships);
if (_.size(requiredAttributes) > 0 && _.isEmpty(attributes.data.attributes)) {
ctx.response.status = 404;
ctx.response.body = 'Missing required attributes';
} else if (!_.isEmpty(_.difference(_.keys(requiredRelationships), _.keys(attributes.data.relationships)))) {
ctx.response.status = 404;
ctx.response.body = 'Missing required relationships';
} else {
cb();
console.log("coucou");
// Looks good
}
} }
// Extract required attributes
const requiredAttributes = _.omit(_.mapValues(strapi.models[attributes.data.type].attributes, function (attr) {
return attr.required ? attr : undefined;
}), _.isUndefined);
// Identify missing attributes
const missingAttributes = _.difference(_.keys(requiredAttributes), _.keys(attributes.data.attributes));
if (!_.isEmpty(missingAttributes)) {
return yield cb({
status: 403,
body: 'Missing required attributes (' + missingAttributes.toString() + ')'
});
}
// Identify required relationships
const relationships = _.indexBy(strapi.models[attributes.data.type].associations, 'alias');
// Extract required relationships
const requiredRelationships = _.intersection(_.keys(requiredAttributes), _.keys(relationships));
// Identify missing relationships
const missingRelationships = _.difference(_.keys(requiredRelationships), _.keys(attributes.data.relationships));
if (!_.isEmpty(missingRelationships)) {
return yield cb({
status: 403,
body: 'Missing required relationships (' + missingRelationships.toString() + ')'
});
}
// Looks good
yield cb();
} }
}; };

View File

@ -39,26 +39,29 @@ module.exports = function (strapi) {
// Wait for downstream middleware/handlers to execute to build the response // Wait for downstream middleware/handlers to execute to build the response
yield next; yield next;
// Verify Content-Type header // Exclude administration routes
if (this.request.type !== 'application/vnd.api+json') { if (!strapi.api.admin.config.routes.hasOwnProperty(this.request.method + ' ' + this.request.url)) {
this.status = 406; // Verify Content-Type header
this.body = ''; if (this.request.type !== 'application/vnd.api+json') {
} else if (this.request.method === 'GET') { this.status = 406;
// Intercept only GET request this.body = '';
} else if (this.request.method === 'GET') {
// Intercept only GET request
// Detect route // Detect route
const matchedRoute = _.find(strapi.router.stack, function (stack) { const matchedRoute = _.find(strapi.router.stack, function (stack) {
if (new RegExp(stack.regexp).test(self.request.url) && _.includes(stack.methods, self.request.method.toUpperCase())) { if (new RegExp(stack.regexp).test(self.request.url) && _.includes(stack.methods, self.request.method.toUpperCase())) {
return stack; return stack;
} }
}); });
// Handlers set the response body // Handlers set the response body
if (!_.isUndefined(matchedRoute)) { if (!_.isUndefined(matchedRoute)) {
const actionRoute = strapi.config.routes[self.request.method.toUpperCase() + ' ' + matchedRoute.path]; const actionRoute = strapi.config.routes[self.request.method.toUpperCase() + ' ' + matchedRoute.path];
if (!_.isUndefined(actionRoute)) { if (!_.isUndefined(actionRoute)) {
response.set(this, matchedRoute, actionRoute); response.set(this, matchedRoute, actionRoute);
}
} }
} }
} }
@ -69,17 +72,29 @@ module.exports = function (strapi) {
cb(); cb();
}, },
parse: function * (next) { /**
// Verify Content-Type header * Parse request and attributes
if (this.request.type !== 'application/vnd.api+json') { */
this.response.status = 406;
this.response.body = ''; parse: function (strapi) {
} else { return function * (next) {
request.parse(this, function * (err) { const self = this;
if (!err) {
// Verify Content-Type header and exclude administration routes
if (strapi.api.admin.config.routes.hasOwnProperty(this.request.method + ' ' + this.request.url)) {
yield next;
} else if (this.request.type !== 'application/vnd.api+json') {
this.response.status = 406;
this.response.body = '';
} else {
yield request.parse(this, function * (err) {
if (err) {
return _.assign(self.response, err);
}
yield next; yield next;
} });
}); }
} }
} }
}; };

View File

@ -87,7 +87,7 @@ module.exports = function (strapi) {
// Add the `globalPolicy`. // Add the `globalPolicy`.
policies.push(globalPolicy(endpoint, value, route)); policies.push(globalPolicy(endpoint, value, route));
policies.push(JSONAPI.parse); policies.push(JSONAPI.parse(strapi));
if (_.isArray(value.policies) && !_.isEmpty(value.policies)) { if (_.isArray(value.policies) && !_.isEmpty(value.policies)) {
_.forEach(value.policies, function (policy) { _.forEach(value.policies, function (policy) {