diff --git a/lib/configuration/hooks/jsonapi/helpers/response.js b/lib/configuration/hooks/jsonapi/helpers/response.js index 9bb01fb113..64973bf833 100644 --- a/lib/configuration/hooks/jsonapi/helpers/response.js +++ b/lib/configuration/hooks/jsonapi/helpers/response.js @@ -21,18 +21,18 @@ module.exports = { */ set: function (ctx, matchedRoute, actionRoute) { - const type = this.getType(actionRoute.controller); const object = this.getObject(matchedRoute); + const type = this.getType(ctx, actionRoute.controller, object).toLowerCase(); const value = this.verifyAndSetValue(ctx, object); - ctx.response.body = this.serialize(ctx, type, value); + ctx.response.body = this.serialize(ctx, type, object, value); }, /** * Serialize response with JSON API specification */ - serialize: function (ctx, type, value) { + serialize: function (ctx, type, object, value) { // TODO: // - Handle configuration with a file to improve flexibility of JSON API support const toSerialize = { @@ -41,11 +41,9 @@ module.exports = { pluralizeType: false, typeForAttribute: function (currentType) { if (strapi.models.hasOwnProperty(type)) { - const tryFindType = _.first(_.reject(_.map(strapi.models[type].associations, function (relation) { + return _.first(_.reject(_.map(strapi.models[type].associations, function (relation) { return (relation.alias === currentType) ? relation.model || relation.collection : undefined; - }), _.isUndefined)); - - return _.isUndefined(tryFindType) ? currentType : tryFindType; + }), _.isUndefined)) || currentType; } } }; @@ -76,7 +74,26 @@ module.exports = { toSerialize.attributes = _.keys(value); } - this.includedRelationShips(ctx, toSerialize, type); + switch (object) { + case 'collection': + this.includedRelationShips(ctx, toSerialize, type); + break; + case 'ressource': + this.includedRelationShips(ctx, toSerialize, type); + break; + case 'relationships': + // Remove data key + delete toSerialize.dataLinks; + delete toSerialize.attributes; + + // Dirty way to set related URL + toSerialize.topLevelLinks.related = toSerialize.topLevelLinks.self.replace('relationships/', ''); + break; + case 'related': + break; + default: + break; + } return new JSONAPISerializer(type, value, toSerialize); }, @@ -98,8 +115,12 @@ module.exports = { ref: self.getPK(relation.model), attributes: _.keys(strapi.models[type].attributes), relationshipLinks: { - self: ctx.request.origin + ctx.request.url + '/relationships/' + relation.alias, - related: ctx.request.origin + ctx.request.url + self: function (record) { + return ctx.request.origin + '/' + type + '/' + record.id + '/relationships/' + relation.alias; + }, + related: function (record) { + return ctx.request.origin + '/' + type + '/' + record.id; + } }, includedLinks: { self: function (data, record) { @@ -116,8 +137,12 @@ module.exports = { typeForAttribute: relation.collection, attributes: _.keys(strapi.models[type].attributes), relationshipLinks: { - self: ctx.request.origin + ctx.request.url + '/relationships/' + relation.alias, - related: ctx.request.origin + ctx.request.url + self: function (record) { + return ctx.request.origin + '/' + type + '/' + record.id + '/relationships/' + relation.alias; + }, + related: function (record) { + return ctx.request.origin + '/' + type + '/' + record.id; + } }, includedLinks: { self: function (data, record) { @@ -174,8 +199,8 @@ module.exports = { // - OtO, MtO: object // Relationships - if (_.isObject(data) || _.isArray(data)) { - return data; + if (_.isObject(data) || _.isArray(data) && data.hasOwnProperty(ctx.params.relation)) { + return data[ctx.params.relation]; } else { return null; } @@ -205,7 +230,6 @@ module.exports = { getObject: function (matchedRoute) { // TODO: // - Improve way to detect collection/ressource/relationships/related - switch (_.size(matchedRoute.regexp.keys)) { case 0: return 'collection'; @@ -222,15 +246,24 @@ module.exports = { * Find data type */ - getType: function (supposedType) { + getType: function (ctx, supposedType, object) { // TODO: // - Parse the URL and try to extract useful information to find the type if (strapi.models.hasOwnProperty(supposedType.toLowerCase())) { - return supposedType.toLowerCase(); - } else { - return null; + switch (object) { + case 'relationships': + return _.first(_.reject(_.map(strapi.models[supposedType.toLowerCase()].associations, function (relation) { + return (ctx.params.hasOwnProperty('relation') && ctx.params.relation === relation.alias) ? relation.model || relation.collection : undefined; + }), _.isUndefined)) || supposedType.toLowerCase(); + case 'related': + return supposedType.toLowerCase(); + default: + return supposedType.toLowerCase(); + } } + + return null; }, /**