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 // Extract required attributes
const requiredAttributes = _.filter(strapi.models[attributes.data.type].attributes, {required:true}); 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 // Identify required relationships
const relationships = _.indexBy(strapi.models[attributes.data.type].associations, 'alias'); const relationships = _.indexBy(strapi.models[attributes.data.type].associations, 'alias');
// Extract required relationships // Extract required relationships
const requiredRelationships = _.intersection(_.keys(requiredAttributes), _.keys(relationships)); const requiredRelationships = _.intersection(_.keys(requiredAttributes), _.keys(relationships));
// Identify missing relationships
const missingRelationships = _.difference(_.keys(requiredRelationships), _.keys(attributes.data.relationships));
console.log(requiredAttributes); if (!_.isEmpty(missingRelationships)) {
console.log(requiredRelationships); return yield cb({
status: 403,
body: 'Missing required relationships (' + missingRelationships.toString() + ')'
});
}
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 // Looks good
} yield cb();
}
} }
}; };

View File

@ -39,6 +39,8 @@ 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;
// Exclude administration routes
if (!strapi.api.admin.config.routes.hasOwnProperty(this.request.method + ' ' + this.request.url)) {
// Verify Content-Type header // Verify Content-Type header
if (this.request.type !== 'application/vnd.api+json') { if (this.request.type !== 'application/vnd.api+json') {
this.status = 406; this.status = 406;
@ -63,25 +65,38 @@ module.exports = function (strapi) {
} }
} }
} }
}
strapi.app.use(interceptor); strapi.app.use(interceptor);
cb(); cb();
}, },
parse: function * (next) { /**
// Verify Content-Type header * Parse request and attributes
if (this.request.type !== 'application/vnd.api+json') { */
parse: function (strapi) {
return function * (next) {
const self = this;
// 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.status = 406;
this.response.body = ''; this.response.body = '';
} else { } else {
request.parse(this, function * (err) { yield request.parse(this, function * (err) {
if (!err) { if (err) {
yield next; return _.assign(self.response, err);
} }
yield next;
}); });
} }
} }
}
}; };
return hook; return hook;

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) {