Generate single query for single type and update core api service

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-01-27 15:11:16 +01:00
parent f20f609324
commit 023bda1f9e
8 changed files with 198 additions and 31 deletions

View File

@ -0,0 +1,28 @@
{
"routes": [
{
"method": "GET",
"path": "/homepage",
"handler": "homepage.find",
"config": {
"policies": []
}
},
{
"method": "PUT",
"path": "/homepage",
"handler": "homepage.update",
"config": {
"policies": []
}
},
{
"method": "DELETE",
"path": "/homepage",
"handler": "homepage.delete",
"config": {
"policies": []
}
}
]
}

View File

@ -0,0 +1,8 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/controllers.html#core-controllers)
* to customize this controller
*/
module.exports = {};

View File

@ -0,0 +1,44 @@
'use strict';
/**
* Lifecycle callbacks for the `homepage` model.
*/
module.exports = {
// Before saving a value.
// Fired before an `insert` or `update` query.
// beforeSave: async (model, attrs, options) => {},
// After saving a value.
// Fired after an `insert` or `update` query.
// afterSave: async (model, response, options) => {},
// Before fetching a value.
// Fired before a `fetch` operation.
// beforeFetch: async (model, columns, options) => {},
// After fetching a value.
// Fired after a `fetch` operation.
// afterFetch: async (model, response, options) => {},
// Before fetching all values.
// Fired before a `fetchAll` operation.
// beforeFetchAll: async (model, columns, options) => {},
// After fetching all values.
// Fired after a `fetchAll` operation.
// afterFetchAll: async (model, response, options) => {},
// Before creating a value.
// Fired before an `insert` query.
// beforeCreate: async (model, attrs, options) => {},
// After creating a value.
// Fired after an `insert` query.
// afterCreate: async (model, attrs, options) => {},
// Before updating a value.
// Fired before an `update` query.
// beforeUpdate: async (model, attrs, options) => {},
// After updating a value.
// Fired after an `update` query.
// afterUpdate: async (model, attrs, options) => {},
// Before destroying a value.
// Fired before a `delete` query.
// beforeDestroy: async (model, attrs, options) => {},
// After destroying a value.
// Fired after a `delete` query.
// afterDestroy: async (model, attrs, options) => {}
};

View File

@ -1,21 +1,17 @@
{
"connection": "default",
"collectionName": "homepage",
"info": {
"name": "Home Page"
"name": "Homepage"
},
"options": {
"increments": true,
"timestamps": [
"created_at",
"updated_at"
]
"timestamps": true
},
"attributes": {
"title": {
"type": "string",
"required": true
"type": "string"
}
},
"kind": "singleType"
"connection": "default",
"kind": "singleType",
"collectionName": "homepages"
}

View File

@ -0,0 +1,8 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/3.0.0-beta.x/concepts/services.html#core-services)
* to customize this service
*/
module.exports = {};

View File

@ -288,11 +288,8 @@ const buildShadowCRUD = models => {
const { kind } = model;
switch (kind) {
case 'singleType': {
// const type = buildSingleType(model);
// mergeSubSchema(type, schema);
break;
}
case 'singleType':
return buildSingleType(model);
default:
return buildCollectionType(model);
}
@ -303,6 +300,81 @@ const buildShadowCRUD = models => {
return schema;
};
const buildSingleType = model => {
const { globalId, plugin, modelName } = model;
const singularName = toSingular(modelName);
const _schema = _.cloneDeep(
_.get(strapi.plugins, 'graphql.config._schema.graphql', {})
);
const globalType = _.get(_schema, ['type', model.globalId], {});
const localSchema = {
definition: '',
query: {},
mutation: {},
resolvers: {
Query: {},
Mutation: {},
// define default resolver for this model
[globalId]: {
id: parent => parent[model.primaryKey] || parent.id,
...buildAssocResolvers(model),
},
},
};
const typeDefObj = buildTypeDefObj(model);
localSchema.definition += generateEnumDefinitions(model.attributes, globalId);
generateDynamicZoneDefinitions(model.attributes, globalId, localSchema);
const description = Schema.getDescription(globalType, model);
const fields = Schema.formatGQL(typeDefObj, globalType, model);
const typeDef = `${description}type ${globalId} {${fields}}\n`;
localSchema.definition += typeDef;
// Add definition to the schema but this type won't be "queriable" or "mutable".
if (globalType === false) {
return localSchema;
}
if (isQueryEnabled(_schema, singularName)) {
const query = Query.composeQueryResolver({
_schema,
plugin,
name: singularName,
});
_.merge(localSchema, {
query: {
// TODO: support all the unique fields
[singularName]: model.globalId,
},
resolvers: {
Query: {
[singularName]: query,
},
},
});
}
// Add model Input definition.
localSchema.definition += Types.generateInputModel(model, modelName);
// build every mutation
['update', 'delete'].forEach(action => {
const mutationScheam = buildMutation({ model, action }, { _schema });
mergeSchemas(localSchema, mutationScheam);
});
return localSchema;
};
const buildCollectionType = model => {
const { globalId, plugin, modelName } = model;

View File

@ -18,10 +18,7 @@ function createCoreApi({ api, model }) {
const userService = _.get(api, ['services', modelName], {});
const userController = _.get(api, ['controllers', modelName], {});
const service = Object.assign(
createService({ model: modelName, strapi }),
userService
);
const service = Object.assign(createService({ model, strapi }), userService);
const controller = Object.assign(
createController({ service, model }),

View File

@ -6,17 +6,22 @@
*/
module.exports = ({ model, strapi }) => {
const { modelName } = model;
if (model.kind === 'singleType') {
return {
find(populate) {
return strapi.entityService.find({ populate }, { model });
return strapi.entityService.find({ populate }, { model: modelName });
},
async createOrUpdate(data, { files } = {}) {
const entity = await this.find();
if (!entity) {
return strapi.entityService.create({ data, files }, { model });
return strapi.entityService.create(
{ data, files },
{ model: modelName }
);
} else {
return strapi.entityService.update(
{
@ -26,7 +31,7 @@ module.exports = ({ model, strapi }) => {
data,
files,
},
{ model }
{ model: modelName }
);
}
},
@ -38,7 +43,7 @@ module.exports = ({ model, strapi }) => {
return strapi.entityService.delete(
{ params: { id: entity.id } },
{ model }
{ model: modelName }
);
},
};
@ -51,7 +56,10 @@ module.exports = ({ model, strapi }) => {
* @return {Promise}
*/
find(params, populate) {
return strapi.entityService.find({ params, populate }, { model });
return strapi.entityService.find(
{ params, populate },
{ model: modelName }
);
},
/**
@ -61,7 +69,10 @@ module.exports = ({ model, strapi }) => {
*/
findOne(params, populate) {
return strapi.entityService.findOne({ params, populate }, { model });
return strapi.entityService.findOne(
{ params, populate },
{ model: modelName }
);
},
/**
@ -71,7 +82,7 @@ module.exports = ({ model, strapi }) => {
*/
count(params) {
return strapi.entityService.count({ params }, { model });
return strapi.entityService.count({ params }, { model: modelName });
},
/**
@ -81,7 +92,7 @@ module.exports = ({ model, strapi }) => {
*/
create(data, { files } = {}) {
return strapi.entityService.create({ data, files }, { model });
return strapi.entityService.create({ data, files }, { model: modelName });
},
/**
@ -91,7 +102,10 @@ module.exports = ({ model, strapi }) => {
*/
update(params, data, { files } = {}) {
return strapi.entityService.update({ params, data, files }, { model });
return strapi.entityService.update(
{ params, data, files },
{ model: modelName }
);
},
/**
@ -101,7 +115,7 @@ module.exports = ({ model, strapi }) => {
*/
delete(params) {
return strapi.entityService.delete({ params }, { model });
return strapi.entityService.delete({ params }, { model: modelName });
},
/**
@ -111,7 +125,7 @@ module.exports = ({ model, strapi }) => {
*/
search(params) {
return strapi.entityService.search({ params }, { model });
return strapi.entityService.search({ params }, { model: modelName });
},
/**
@ -120,7 +134,7 @@ module.exports = ({ model, strapi }) => {
* @return {Promise}
*/
countSearch(params) {
return strapi.entityService.countSearch({ params }, { model });
return strapi.entityService.countSearch({ params }, { model: modelName });
},
};
};