Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(graphql): allow to pass cache hints to graphql fields #20254

Closed
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@
"pluginOptions": {
"i18n": {
"localized": true
},
"graphql": {
"cacheHint": {
"find": {
"maxAge": 1000,
"scope": "PUBLIC"
},
"findOne": {
"maxAge": 2000,
"scope": "PUBLIC"
}
}
}
},
"attributes": {
Expand All @@ -30,7 +42,15 @@
"type": "relation",
"relation": "manyToMany",
"target": "api::address.address",
"mappedBy": "categories"
"mappedBy": "categories",
"pluginOptions": {
"graphql": {
"cacheHint": {
"maxAge": 10,
"scope": "PUBLIC"
}
}
}
},
"temps": {
"type": "relation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const dtoFields = [
'options',
'pluginOptions',
'attributes',
'pluginOptions',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Removed duplicated value.

];

export default () => ({
Expand Down
7 changes: 7 additions & 0 deletions packages/core/types/src/types/core/schemas/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Attribute, Common } from '../..';
import type { CacheHint } from 'apollo-server-types';

/**
* Literal union type representing the possible natures of a content type
Expand Down Expand Up @@ -97,6 +98,12 @@ export interface Options {

export interface PluginOptions {
i18n?: { localized: boolean };
graphql?: {
cacheHint?: {
find?: CacheHint;
findOne?: CacheHint;
}
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why is this field type not visible in find/findOne resolvers? 🤔

}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/plugins/graphql/server/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApolloServer } from 'apollo-server-koa';
import {
ApolloServerPluginLandingPageDisabled,
ApolloServerPluginLandingPageGraphQLPlayground,
ApolloServerPluginCacheControl,
} from 'apollo-server-core';
import depthLimit from 'graphql-depth-limit';
import { graphqlUploadKoa } from 'graphql-upload';
Expand Down Expand Up @@ -74,6 +75,8 @@ export async function bootstrap({ strapi }: { strapi: Strapi }) {
bodyParserConfig: true,

plugins: [
// TODO: Remove this. Will be added by user in config if they want to enable cache
ApolloServerPluginCacheControl({ defaultMaxAge: 3600 }),
process.env.NODE_ENV === 'production' && !config('playgroundAlways')
? ApolloServerPluginLandingPageDisabled()
: ApolloServerPluginLandingPageGraphQLPlayground(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ export default ({ strapi }: Context) => {

args: getContentTypeArgs(contentType, { multiple: false }),

async resolve(parent, args, ctx) {
async resolve(parent, args, ctx, info) {
// TODO: pluginOptions.graphql not recognised
if ((contentType.pluginOptions as any)?.graphql?.cacheHint?.findOne) {
info.cacheControl.setCacheHint((contentType.pluginOptions as any).graphql.cacheHint.findOne);
}

const transformedArgs = transformArgs(args, { contentType });

const { findOne } = getService('builders')
Expand Down Expand Up @@ -106,7 +111,12 @@ export default ({ strapi }: Context) => {

args: getContentTypeArgs(contentType),

async resolve(parent, args, ctx) {
async resolve(parent, args, ctx, info) {
// TODO: pluginOptions.graphql not recognised
if ((contentType.pluginOptions as any)?.graphql?.cacheHint?.find) {
info.cacheControl.setCacheHint((contentType.pluginOptions as any).graphql.cacheHint.find);
}

const transformedArgs = transformArgs(args, { contentType, usePagination: true });

const { find } = getService('builders')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ export default ({ strapi }: Context) => {

args: getContentTypeArgs(contentType),

async resolve(parent, args, ctx) {
async resolve(parent, args, ctx, info) {
// TODO: pluginOptions.graphql not recognised
if ((contentType.pluginOptions as any)?.graphql?.cacheHint?.findOne) {
info.cacheControl.setCacheHint((contentType.pluginOptions as any).graphql.cacheHint.findOne);
}

const transformedArgs = transformArgs(args, { contentType });

const queriesResolvers = getService('builders')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { CacheHint } from 'apollo-server-types';
import { get } from 'lodash/fp';
import { sanitize, validate, pipeAsync, errors } from '@strapi/utils';
import type { UID } from '@strapi/types';

import type { Context } from '../../types';
import { FieldResolver } from 'nexus';

const { ApplicationError } = errors;

Expand All @@ -17,10 +19,12 @@ export default ({ strapi }: Context) => {
buildAssociationResolver({
contentTypeUID,
attributeName,
cacheHint,
}: {
contentTypeUID: UID.ContentType;
attributeName: string;
}) {
cacheHint?: CacheHint;
}): FieldResolver<string, string> {
const contentType = strapi.getModel(contentTypeUID);
const attribute: any = contentType.attributes[attributeName];

Expand All @@ -38,7 +42,11 @@ export default ({ strapi }: Context) => {

const targetContentType = strapi.getModel(targetUID);

return async (parent: any, args: any = {}, context: any = {}) => {
return async (parent: any, args: any = {}, context: any = {}, resolveInfo) => {
if (cacheHint) {
resolveInfo.cacheControl.setCacheHint(cacheHint);
}

const { auth } = context.state;

const transformedArgs = transformArgs(args, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import type { CacheHint } from 'apollo-server-types';
import { sanitize, validate } from '@strapi/utils';
import type { Attribute, UID } from '@strapi/types';

import type { Context } from '../../types';
import { FieldResolver } from 'nexus';

export default ({ strapi }: Context) => ({
buildComponentResolver({
contentTypeUID,
attributeName,
cacheHint,
}: {
contentTypeUID: UID.ContentType;
attributeName: string;
}) {
cacheHint?: CacheHint;
}): FieldResolver<string, string> {
const { transformArgs } = strapi.plugin('graphql').service('builders').utils;

return async (parent: any, args: any, ctx: any) => {
return async (parent: any, args: any, ctx: any, info) => {
if (cacheHint) {
info.cacheControl.setCacheHint(cacheHint);
}

const contentType = strapi.getModel(contentTypeUID);

const { component: componentName } = contentType.attributes[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import type { CacheHint } from 'apollo-server-types';
import type { UID } from '@strapi/types';

import type { Context } from '../../types';
import { FieldResolver } from 'nexus';

export default ({ strapi }: Context) => ({
buildDynamicZoneResolver({
contentTypeUID,
attributeName,
cacheHint,
}: {
contentTypeUID: UID.ContentType;
attributeName: string;
}) {
return async (parent: any) => {
cacheHint?: CacheHint;
}): FieldResolver<string, string> {
return async (parent, _args, _context, info) => {
if (cacheHint) {
info.cacheControl.setCacheHint(cacheHint);
}

return strapi.entityService!.load(contentTypeUID, parent, attributeName);
};
},
Expand Down