diff --git a/docusaurus/docs/cms/api/graphql.md b/docusaurus/docs/cms/api/graphql.md index d2fd3521fd..0e1853d81e 100644 --- a/docusaurus/docs/cms/api/graphql.md +++ b/docusaurus/docs/cms/api/graphql.md @@ -76,7 +76,6 @@ The GraphQL API does not support media upload. Use the [REST API `POST /upload` The GraphQL API exposes documents using only the `documentId` field. The previous numeric `id` is no longer available here, although it is still returned by the REST API for backward compatibility (see [breaking change](/cms/migration/v4-to-v5/breaking-changes/use-document-id) for details). ::: - ## Queries Queries in GraphQL are used to fetch data without modifying it. @@ -1111,3 +1110,12 @@ mutation DeleteRestaurant($documentId: ID!, $locale: I18NLocaleCode) { } } ``` + +## Advanced use cases + +Click on the following cards for short guides on more advanced use cases leveraging the GraphQL API and Strapi features: + + + + + \ No newline at end of file diff --git a/docusaurus/docs/cms/api/graphql/advanced-policies.md b/docusaurus/docs/cms/api/graphql/advanced-policies.md new file mode 100644 index 0000000000..6f42fc2a1a --- /dev/null +++ b/docusaurus/docs/cms/api/graphql/advanced-policies.md @@ -0,0 +1,64 @@ +--- +title: Advanced policies for GraphQL +displayed_sidebar: cmsSidebar +tags: + - GraphQL API + - policies +--- + +# Advanced policies for the GraphQL API + +Requests sent to the [GraphQL API](/cms/api/graphql) pass through Strapi's [middlewares](/cms/backend-customization/middlewares.md) and [policies](/cms/backend-customization/policies.md) system. Policies can be attached to resolvers to implement complex authorization rules, as shown in the present short guide. + +For additional information on GraphQL policies, please refer to the [GraphQL plugin configuration](/cms/plugins/graphql#extending-the-schema) documentation. + +## Conditional visibility + +To limit the number of returned entries for unauthenticated users you can write a policy that modifies resolver arguments: + +```ts title="/src/policies/limit-public-results.ts" +export default async (policyContext, config, { strapi }) => { + const { state, args } = policyContext; + + if (!state.user) { + args.limit = 4; // only return 4 results for public + } + + return true; +}; +``` + +Register the policy in `/config/policies.ts` and apply it to a resolver: + +```ts title="/config/policies.ts" +export default { + 'api::restaurant.restaurant': { + find: [ 'global::limit-public-results' ], + }, +}; +``` + +## Group membership + +Policies can access `policyContext.state.user` to check group membership, as in the following example: + +```ts title="/src/policies/is-group-member.ts" +export default async ({ state }, config, { strapi }) => { + const userGroups = await strapi.query('plugin::users-permissions.group').findMany({ + where: { users: { id: state.user.id } }, + }); + return userGroups.some(g => g.name === config.group); +}; +``` + +Use the policy with the following configuration: + +```ts title="/config/policies.ts" +export default { + 'api::restaurant.restaurant': { + find: [{ name: 'global::is-group-member', config: { group: 'editors' } }], + }, +}; +``` + +With this setup the resolver only returns results if the authenticated user belongs to the `editors` group. diff --git a/docusaurus/docs/cms/api/graphql/advanced-queries.md b/docusaurus/docs/cms/api/graphql/advanced-queries.md new file mode 100644 index 0000000000..8db3a4d05f --- /dev/null +++ b/docusaurus/docs/cms/api/graphql/advanced-queries.md @@ -0,0 +1,52 @@ +--- +title: Advanced queries for GraphQL +displayed_sidebar: cmsSidebar +tags: + - GraphQL API +--- + +# Advanced queries for the GraphQL API + +Strapi's [GraphQL API](/cms/api/graphql) resolves many queries automatically, but complex data access can require deeper relation fetching or chaining resolvers. The present short guide explains how to handle such advanced scenarios. + +For additional information, please refer to the [GraphQL customization](/cms/plugins/graphql#extending-the-schema) documentation. + +## Multi-level queries + +Use nested selection sets to fetch relations several levels deep, as in the following example: + +```graphql +{ + restaurants { + documentId + name + categories { + documentId + name + parent { + documentId + name + } + } + } +} +``` + +The GraphQL plugin automatically resolves nested relations. If you need to apply custom logic at a specific level, create a custom resolver for that field. + +## Resolver chains + +Custom resolvers can call other resolvers to reuse existing logic. A common pattern is to resolve permissions or context data in a parent resolver and pass it down to child resolvers, as in the following example: + +```js title="/src/api/restaurant/resolvers/restaurant.ts" +export default { + Query: { + restaurants: async (parent, args, ctx) => { + const documents = await strapi.documents('api::restaurant.restaurant').findMany(args); + return documents.map(doc => ctx.request.graphql.resolve('Restaurant', doc)); + }, + }, +}; +``` + +In this example the parent resolver fetches restaurants using the [Document Service API](/cms/api/document-service), then delegates to the generated `Restaurant` resolver provided by the plugin so default behavior such as field selection still applies. diff --git a/docusaurus/docs/cms/plugins/graphql.md b/docusaurus/docs/cms/plugins/graphql.md index 834fc561ea..58450f0512 100644 --- a/docusaurus/docs/cms/plugins/graphql.md +++ b/docusaurus/docs/cms/plugins/graphql.md @@ -673,6 +673,10 @@ When [extending the GraphQL schema](#extending-the-schema), the `resolversConfig * [policies with the `policies`](#policies) key * and [middlewares with the `middlewares`](#middlewares) key +:::tip +The [advanced queries](/cms/api/graphql/advanced-queries) guide might contain additional information suitable for your use case, including multi-level queries and custom resolvers examples. +::: + ###### Authorization configuration By default, the authorization of a GraphQL request is handled by the registered authorization strategy that can be either [API token](/cms/features/api-tokens) or through the [Users & Permissions plugin](#usage-with-the-users--permissions-plugin). The Users & Permissions plugin offers a more granular control. @@ -877,6 +881,10 @@ export default { +:::tip +The [advanced policies](/cms/api/graphql/advanced-policies) guide might contain additional information suitable for your use case. +::: + ###### Middlewares [Middlewares](/cms/backend-customization/middlewares) can be applied to a GraphQL resolver through the `resolversConfig.[MyResolverName].middlewares` key. The only difference between the GraphQL and REST implementations is that the `config` key becomes `options`.