Last active
February 6, 2021 13:53
-
-
Save u007/6f4a836ea99ee4f6adae921e850f1839 to your computer and use it in GitHub Desktop.
strapi graphql with nested field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { find2 } = require('../controllers/category') | |
module.exports = { | |
definition: ` | |
type Category2 { | |
id: ID! | |
created_at: DateTime! | |
updated_at: DateTime! | |
Title: String | |
Icon: String | |
Body: String | |
Articles(sort: String, limit: Int, start: Int, where: JSON): [Article] | |
} | |
`, | |
query: ` | |
categories2( | |
sort: String | |
limit: Int | |
start: Int | |
where: JSON | |
publicationState: PublicationState | |
): [Category2] | |
`, | |
type: { | |
}, | |
resolver: { | |
Query: { | |
categories2: { | |
description: 'Return the categories with articles', | |
resolver: find2, | |
resolverOf: 'application::category.category.find2' | |
} | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const graphqlFields = require('graphql-fields'); | |
const { queryBuilder, graphqlArgToQueryParam } = require('../../_utils/query'); | |
module.exports = { | |
async find2(root, options = {}, graphqlContext, info) { | |
const ctx = graphqlContext.context; | |
const params = ctx.params | |
const fields = graphqlFields(info, {}, { processArguments: true }); | |
const res = await queryBuilder(strapi.query('section').model, params).fetchAll({ withRelated: [] }); | |
const list = [] | |
for await (let row of res) { | |
// console.debug('row', row.attributes); | |
const category = row.attributes; | |
if ('Articles' in fields) { | |
const articleQuery = fields.Articles; | |
const articleParam = graphqlArgToQueryParam(articleQuery.__arguments); | |
const articleWhere = articleParam._where || {}; | |
articleWhere.category_in = [category.id]; | |
articleParam._where = articleWhere; | |
console.debug('articles query', articleQuery.__arguments, articleParam); | |
const articleList = await strapi.query('article').find(articleParam); | |
category.Articles = articleList.map((articleRow) => { | |
// console.debug('res', articleRow) | |
return articleRow; | |
}); | |
} | |
list.push(category); | |
} | |
return list | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
graphqlArgToQueryParam(grapqlArgs) { | |
const res = {} | |
for(var arg of grapqlArgs) { | |
for (var key of Object.keys(arg)) { | |
switch (key) { | |
case 'limit': | |
res._limit = parseInt(arg[key].value, 10); | |
break; | |
case 'start': | |
res._start = parseInt(arg[key].value, 10); | |
break; | |
case 'where': | |
res._where = arg[key].value; | |
default: | |
}; | |
} | |
} | |
return res; | |
}, | |
queryBuilder(model, params) { | |
console.debug('queryBuilder params', params); | |
const limit = params._limit || 100 | |
const start = parseInt(params._start, 10) || 0 | |
return model.query((qb) => { | |
qb.debug(true); | |
for (let field in params._where) { | |
const value = params._where[field] | |
// console.log("cond", field, value); | |
const lastPos = field.lastIndexOf('_'); | |
const justField = lastPos >= 0 ? field.substr(0, lastPos) : field; | |
if (field.endsWith('_ne')) { | |
field = field.substr(0, field.length - 3); | |
if (value == 'null') { | |
qb.where(field, 'is not', null); | |
} else { | |
qb.where(field, '<>', value); | |
} | |
} else if (field.endsWith('_lt')) { | |
qb.where(justField, '<', value); | |
} else if (field.endsWith('_gt')) { | |
qb.where(justField, '>', value); | |
} else if (field.endsWith('_lte')) { | |
qb.where(justField, '<=', value); | |
} else if (field.endsWith('_gte')) { | |
qb.where(justField, '>=', value); | |
} else if (field.endsWith('_in')) { | |
qb.where(justField, 'in', value); | |
} else if (field.endsWith('_nin')) { | |
qb.where(justField, 'not in', value); | |
} else if (field.endsWith('_contains')) { | |
qb.where(justField, 'like', '%' + value + '%'); | |
} else if (field.endsWith('_ncontains')) { | |
qb.where(justField, 'not like', '%' + value + '%'); | |
} else if (field.endsWith('_containss')) { | |
//TODO permission denied | |
qb.where(justField, 'like binary', '%' + value + '%'); | |
} else if (field.endsWith('_ncontainss')) { | |
//TODO permission denid | |
qb.where(justField, 'not like binary', '%' + value + '%'); | |
} else if (field.endsWith('_null')) { | |
qb.where(justField, 'is null'); | |
} else if (field.endsWith('_eq')) { | |
qb.where(justField, '=', value); | |
} | |
else { | |
qb.where(field, '=', value); | |
} | |
} | |
if (params._sort) { | |
const [sortField, sortDir] = params._sort.split(':'); | |
// console.debug('sort?', sortField, sortDir); | |
if (sortDir) { | |
qb.orderBy(sortField, sortDir); | |
} else { | |
qb.orderBy(sortField, 'asc'); | |
} | |
} | |
qb.limit(limit); | |
qb.offset(start); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment