Improve errors display and display only existing link

This commit is contained in:
Aurélien Georget 2016-01-29 17:56:57 +01:00
parent 744bf74069
commit 06549e6bb7
4 changed files with 75 additions and 24 deletions

View File

@ -41,7 +41,9 @@ module.exports = {
default:
throw {
status: 403,
body: 'Invalid HTTP method'
body: {
message: 'Invalid HTTP method'
}
};
}
},
@ -69,22 +71,30 @@ module.exports = {
if (!body.hasOwnProperty('data')) {
throw {
status: 403,
body: 'Missing `data` member'
body: {
message: 'Missing `data` member'
}
};
} else if (!utils.isRessourceObject(body.data) && ctx.method !== 'POST') {
throw {
status: 403,
body: 'Invalid ressource object'
body: {
message: 'Invalid ressource object'
}
};
} else if (!body.data.hasOwnProperty('type') && ctx.method === 'POST') {
throw {
status: 403,
body: 'Invalid ressource object'
body: {
message: 'Invalid ressource object'
}
};
} else if (!strapi.models.hasOwnProperty(body.data.type)) {
throw {
status: 403,
body: 'Unknow `type` ' + body.data.type
body: {
message: 'Unknow `type` ' + body.data.type
}
};
}
@ -98,7 +108,9 @@ module.exports = {
if (!_.isEmpty(missingAttributes)) {
throw {
status: 403,
body: 'Missing required attributes (' + missingAttributes.toString() + ')'
body: {
message: 'Missing required attributes (' + missingAttributes.toString() + ')'
}
};
}
@ -112,7 +124,9 @@ module.exports = {
if (!_.isEmpty(missingRelationships)) {
throw {
status: 403,
body: 'Missing required relationships (' + missingRelationships.toString() + ')'
body: {
message: 'Missing required relationships (' + missingRelationships.toString() + ')'
}
};
}
@ -120,15 +134,22 @@ module.exports = {
if (_.size(requiredRelationships)) {
const errors = _.remove(_.flattenDeep(_.map(body.data.relationships, function (relation, key) {
if (!relation.hasOwnProperty('data')) {
return 'Missing `data` member for relationships ' + relation;
return {
message: 'Missing `data` member for relationships ' + relation
};
} else if (_.isArray(relation.data)) {
return _.map(relation.data, function (ressource) {
return _.map(relation.data, function (ressource, position) {
if (!utils.isRessourceObject(ressource)) {
return 'Invalid ressource object in relationships ' + key;
return {
position: position,
message: 'Invalid ressource object in relationships ' + key
};
}
});
} else if (!utils.isRessourceObject(relation.data)) {
return 'Invalid ressource object for relationships ' + key;
return {
message: 'Invalid ressource object for relationships ' + key
};
}
})), function (n) {
return !_.isUndefined(n);
@ -137,7 +158,7 @@ module.exports = {
if (!_.isEmpty(errors)) {
throw {
status: 403,
body: errors.toString()
body: errors
};
}
}

View File

@ -31,18 +31,20 @@ module.exports = {
ctx.response.status = 404;
ctx.response.body = '';
return false;
return;
} else if (ctx.method === 'DELETE') {
// Request successful and responds with only top-level meta data or nothing.
ctx.response.body = '';
return false;
return;
}
// Fetch and format value
const value = this.fetchValue(ctx, object);
ctx.response.body = this.serialize(ctx, type, object, value);
if (!_.isEmpty(value)) {
ctx.response.body = this.serialize(ctx, type, object, value);
}
},
/**
@ -132,6 +134,11 @@ module.exports = {
if (strapi.models.hasOwnProperty(type)) {
_.forEach(strapi.models[type].associations, function (relation) {
const PK = utils.getPK(relation.model) || utils.getPK(relation.collection);
const availableRoutes = {
relSlSelf: utils.isRoute('GET /' + type + '/:' + PK + '/relationships/:relation'),
relSlRelated: utils.isRoute('GET /' + type + '/:' + PK),
incSelf: relation.model ? utils.isRoute('GET /' + relation.model + '/:' + PK) : utils.isRoute('GET /' + relation.collection + '/:' + PK)
};
switch (relation.nature) {
case 'oneToOne':
@ -139,24 +146,30 @@ module.exports = {
// Object
toSerialize[relation.alias] = {
ref: PK,
attributes: _.keys(strapi.models[type].attributes),
attributes: _.keys(_.omit(strapi.models[type].attributes, _.isFunction)),
relationshipLinks: {
self: function (record) {
if (record.hasOwnProperty(PK)) {
if (record.hasOwnProperty(PK) && availableRoutes.relSlSelf) {
return ctx.request.origin + '/' + type + '/' + record[PK] + '/relationships/' + relation.alias;
}
return undefined;
},
related: function (record) {
if (record.hasOwnProperty(PK)) {
if (record.hasOwnProperty(PK) && availableRoutes.relSlRelated) {
return ctx.request.origin + '/' + type + '/' + record[PK];
}
return undefined;
}
},
includedLinks: {
self: function (data, record) {
if (!_.isUndefined(record) && record.hasOwnProperty(PK)) {
if (!_.isUndefined(record) && record.hasOwnProperty(PK) && availableRoutes.incSelf) {
return ctx.request.origin + '/' + relation.model + '/' + record[PK];
}
return undefined;
}
}
};
@ -167,24 +180,30 @@ module.exports = {
toSerialize[relation.alias] = {
ref: PK,
typeForAttribute: relation.collection,
attributes: _.keys(strapi.models[type].attributes),
attributes: _.keys(_.omit(strapi.models[type].attributes, _.isFunction)),
relationshipLinks: {
self: function (record) {
if (record.hasOwnProperty(PK)) {
if (record.hasOwnProperty(PK) && availableRoutes.relSlSelf) {
return ctx.request.origin + '/' + type + '/' + record[PK] + '/relationships/' + relation.alias;
}
return undefined;
},
related: function (record) {
if (record.hasOwnProperty(PK)) {
if (record.hasOwnProperty(PK) && availableRoutes.relSlRelated) {
return ctx.request.origin + '/' + type + '/' + record[PK];
}
return undefined;
}
},
includedLinks: {
self: function (data, record) {
if (record.hasOwnProperty(PK)) {
if (record.hasOwnProperty(PK) && availableRoutes.incSelf) {
return ctx.request.origin + '/' + relation.collection + '/' + record[PK];
}
return undefined;
}
}
};

View File

@ -31,6 +31,9 @@ module.exports = function (strapi) {
// Exclude administration routes
if (this.request.url.indexOf('admin') === -1) {
// Set the required header
this.response.type = 'application/vnd.api+json';
// Verify Content-Type header
if (this.request.type !== 'application/vnd.api+json') {
this.status = 406;
@ -56,7 +59,7 @@ module.exports = function (strapi) {
} else {
// Intercept error requests
this.body = {
error: this.body
errors: this.body
};
}
}

View File

@ -21,6 +21,14 @@ module.exports = {
return _.isObject(object) && object.hasOwnProperty('id') && object.hasOwnProperty('type');
},
/**
* Verify if the route exists
*/
isRoute: function (link) {
return strapi.config.routes.hasOwnProperty(link);
},
/**
* Find data object
*/