mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 07:33:17 +00:00
Support relationships for collection and ressource
This commit is contained in:
parent
2868ce08ee
commit
23b306c576
@ -25,55 +25,110 @@ module.exports = {
|
||||
const object = this.getObject(matchedRoute);
|
||||
const value = this.verifyAndSetValue(ctx, object);
|
||||
|
||||
ctx.response.body = this.serialize(ctx, type, object, value);
|
||||
ctx.response.body = this.serialize(ctx, type, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Serialize response with JSON API specification
|
||||
*/
|
||||
|
||||
serialize: function (ctx, type, object, value) {
|
||||
serialize: function (ctx, type, value) {
|
||||
// TODO:
|
||||
// - Handle configuration with a file to improve flexibility of JSON API support
|
||||
const toSerialize = {
|
||||
topLevelLinks: {self: ctx.request.origin + ctx.request.url}
|
||||
topLevelLinks: {self: ctx.request.origin + ctx.request.url},
|
||||
keyForAttribute: 'camelCase',
|
||||
pluralizeType: false,
|
||||
typeForAttribute: function (currentType) {
|
||||
if (strapi.models.hasOwnProperty(type)) {
|
||||
const tryFindType = _.first(_.reject(_.map(strapi.models[type].associations, function (relation) {
|
||||
return (relation.alias === currentType) ? relation.model || relation.collection : undefined;
|
||||
}), _.isUndefined));
|
||||
|
||||
return _.isUndefined(tryFindType) ? currentType : tryFindType;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
switch (object) {
|
||||
case 'collection':
|
||||
if (!_.isEmpty(value) && _.isArray(value)) {
|
||||
const PK = this.getPK(type);
|
||||
|
||||
// TODO :
|
||||
// - Detect PK and stringify the value
|
||||
_.forEach(value, function (value) {
|
||||
value.id = value.id.toString();
|
||||
});
|
||||
if (_.isArray(value) && !_.isEmpty(value)) {
|
||||
// Array
|
||||
if (!_.isNull(PK)) {
|
||||
_.forEach(value, function (record) {
|
||||
record[PK] = record[PK].toString();
|
||||
});
|
||||
}
|
||||
|
||||
toSerialize.dataLinks = {
|
||||
self: function (record) {
|
||||
return ctx.request.origin + ctx.request.url + '/' + record.id;
|
||||
}
|
||||
};
|
||||
} else if (!_.isEmpty(value) && _.isObject(value)) {
|
||||
// TODO :
|
||||
// - Detect PK and stringify the value
|
||||
toSerialize.dataLinks = {
|
||||
self: function (record) {
|
||||
return ctx.request.origin + ctx.request.url + '/' + record.id;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO :
|
||||
// - Parse the model based on the type value
|
||||
// - Displayed attributes but also consider query parameters
|
||||
toSerialize.attributes = _.keys(value[0]);
|
||||
} else if (_.isObject(value) && !_.isEmpty(value)) {
|
||||
// Object
|
||||
if (!_.isNull(PK)) {
|
||||
value[PK] = value[PK].toString();
|
||||
}
|
||||
|
||||
toSerialize.attributes = ['id'];
|
||||
toSerialize.attributes = _.keys(value);
|
||||
}
|
||||
|
||||
return new JSONAPISerializer(type, value, toSerialize);
|
||||
case 'ressource':
|
||||
toSerialize.attributes = ['id'];
|
||||
this.includedRelationShips(ctx, toSerialize, type);
|
||||
|
||||
return new JSONAPISerializer(type, value, toSerialize);
|
||||
case 'relationships':
|
||||
break;
|
||||
case 'related':
|
||||
break;
|
||||
default:
|
||||
return new JSONAPISerializer(type, value, toSerialize);
|
||||
return new JSONAPISerializer(type, value, toSerialize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Include relationships values to the object
|
||||
*/
|
||||
|
||||
includedRelationShips: function (ctx, toSerialize, type) {
|
||||
const self = this;
|
||||
|
||||
if (strapi.models.hasOwnProperty(type)) {
|
||||
_.forEach(strapi.models[type].associations, function (relation) {
|
||||
switch (relation.nature) {
|
||||
case 'oneToOne':
|
||||
case 'manyToOne':
|
||||
// Object
|
||||
toSerialize[relation.alias] = {
|
||||
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
|
||||
},
|
||||
includedLinks: {
|
||||
self: function (data, record) {
|
||||
return ctx.request.origin + '/' + relation.model + '/' + record.id;
|
||||
}
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'oneToMany':
|
||||
case 'manyToMany':
|
||||
// Array
|
||||
toSerialize[relation.alias] = {
|
||||
ref: self.getPK(relation.collection),
|
||||
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
|
||||
},
|
||||
includedLinks: {
|
||||
self: function (data, record) {
|
||||
return ctx.request.origin + '/' + relation.collection + '/' + record.id;
|
||||
}
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@ -148,16 +203,15 @@ module.exports = {
|
||||
*/
|
||||
|
||||
getObject: function (matchedRoute) {
|
||||
// Top level route
|
||||
// TODO:
|
||||
// - Improve way to detect collection/ressource/relationships/related
|
||||
|
||||
switch (_.size(matchedRoute.regexp.keys)) {
|
||||
case 0:
|
||||
// Collection
|
||||
return 'collection';
|
||||
case 1:
|
||||
// Ressource
|
||||
return 'ressource';
|
||||
case 2:
|
||||
// Relationships or related ressource
|
||||
return (matchedRoute.path.indexOf('relationships')) ? 'relationships' : 'related';
|
||||
default:
|
||||
return 'collection';
|
||||
@ -169,10 +223,35 @@ module.exports = {
|
||||
*/
|
||||
|
||||
getType: function (supposedType) {
|
||||
// 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 'Unknow';
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Find primary key
|
||||
*/
|
||||
|
||||
getPK: function (type) {
|
||||
if (!strapi.models.hasOwnProperty(type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const PK = _.findKey(strapi.models[type].attributes, {primaryKey: true});
|
||||
|
||||
if (!_.isUndefined(PK)) {
|
||||
return PK;
|
||||
} else if (strapi.models[type].attributes.hasOwnProperty('id')) {
|
||||
return 'id';
|
||||
} else if (strapi.models[type].attributes.hasOwnProperty('uuid')) {
|
||||
return 'uuid';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user