diff --git a/api/src/app.ts b/api/src/app.ts index 25a1ef1653..e851e17ae2 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -7,7 +7,6 @@ import { createRequire } from 'node:module'; import path from 'path'; import qs from 'qs'; import { registerAuthProviders } from './auth.js'; -import { flushCaches } from './cache.js'; import activityRouter from './controllers/activity.js'; import assetsRouter from './controllers/assets.js'; import authRouter from './controllers/auth.js'; @@ -91,8 +90,6 @@ export default async function createApp(): Promise { logger.warn(`Database migrations have not all been run`); } - await flushCaches(); - await registerAuthProviders(); const extensionManager = getExtensionManager(); diff --git a/api/src/database/migrations/run.ts b/api/src/database/migrations/run.ts index 1d5d5d79aa..2ab03a5917 100644 --- a/api/src/database/migrations/run.ts +++ b/api/src/database/migrations/run.ts @@ -5,6 +5,7 @@ import { orderBy } from 'lodash-es'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import path from 'path'; +import { flushCaches } from '../../cache.js'; import env from '../../env.js'; import logger from '../../logger.js'; import type { Migration } from '../../types/index.js'; @@ -77,6 +78,8 @@ export default async function run(database: Knex, direction: 'up' | 'down' | 'la await up(database); await database.insert({ version: nextVersion.version, name: nextVersion.name }).into('directus_migrations'); + + await flushCaches(true); } async function down() { @@ -100,11 +103,16 @@ export default async function run(database: Knex, direction: 'up' | 'down' | 'la await down(database); await database('directus_migrations').delete().where({ version: migration.version }); + + await flushCaches(true); } async function latest() { + let needsCacheFlush = false; + for (const migration of migrations) { if (migration.completed === false) { + needsCacheFlush = true; const { up } = await import(`file://${migration.file}`); if (log) { @@ -115,5 +123,9 @@ export default async function run(database: Knex, direction: 'up' | 'down' | 'la await database.insert({ version: migration.version, name: migration.name }).into('directus_migrations'); } } + + if (needsCacheFlush) { + await flushCaches(true); + } } } diff --git a/api/src/utils/get-cache-key.test.ts b/api/src/utils/get-cache-key.test.ts index 963878d74b..fe93c55e4a 100644 --- a/api/src/utils/get-cache-key.test.ts +++ b/api/src/utils/get-cache-key.test.ts @@ -3,6 +3,8 @@ import { afterEach, beforeAll, describe, expect, SpyInstance, test, vi } from 'v import { getCacheKey } from './get-cache-key.js'; import * as getGraphqlQueryUtil from './get-graphql-query-and-variables.js'; +vi.mock('./package.js', () => ({ version: '1.2.3' })); + const baseUrl = 'http://localhost'; const restUrl = `${baseUrl}/items/example`; const graphQlUrl = `${baseUrl}/graphql`; @@ -13,42 +15,42 @@ const requests = [ { name: 'as unauthenticated request', params: { method, originalUrl: restUrl }, - key: '17da8272c9a0ec6eea38a37d6d78bddeb7c79045', + key: '20ada3d7cc37fb7e742d2a723f6f1d7a64686d2e', }, { name: 'as authenticated request', params: { method, originalUrl: restUrl, accountability }, - key: '99a6394222a3d7d149ac1662fc2fff506932db58', + key: '79daba5bf38b6b80cb4bf4e2de95d6a8380f7927', }, { name: 'a request with a fields query', params: { method, originalUrl: restUrl, sanitizedQuery: { fields: ['id', 'name'] } }, - key: 'aa6e2d8a78de4dfb4af6eaa230d1cd9b7d31ed19', + key: 'e1839f7379b39188622e797fdbe2e3e6d477cbdc', }, { name: 'a request with a filter query', params: { method, originalUrl: restUrl, sanitizedQuery: { filter: { name: { _eq: 'test' } } } }, - key: 'd7eb8970f0429e1cf85e12eb5bb8669f618b09d3', + key: '0bcc9af5f628db85043133e59226b2de154d7183', }, { name: 'a GraphQL GET query request', params: { method, originalUrl: graphQlUrl, query: { query: 'query { test { id } }' } }, - key: '201731b75c627c60554512d819b6935b54c73814', + key: '14bc276cf21e2d22334b84841533e2c8e1bba9bd', }, { name: 'a GraphQL POST query request', params: { method: 'POST', originalUrl: graphQlUrl, body: { query: 'query { test { name } }' } }, - key: '64eb0c48ea69d0863ff930398f29b5c7884f88f7', + key: 'c5bf03e138e0f7bbaa50dde9cad554bef47a81d2', }, { name: 'an authenticated GraphQL GET query request', params: { method, originalUrl: graphQlUrl, accountability, query: { query: 'query { test { id } }' } }, - key: '9bc52c98dcf2de04c64589f52e0ada1e38d53a90', + key: '981f27be4c0cfed0b4eca6ac2514f6629aea6be1', }, { name: 'an authenticated GraphQL POST query request', params: { method: 'POST', originalUrl: graphQlUrl, accountability, body: { query: 'query { test { name } }' } }, - key: '051ea77ce5ba71bbc88bcb567b9ddc602b585c13', + key: '358336a2c61f7ea2b41b5c1566bbebe692be601d', }, ]; diff --git a/api/src/utils/get-cache-key.ts b/api/src/utils/get-cache-key.ts index 9572b27920..eac3c8680b 100644 --- a/api/src/utils/get-cache-key.ts +++ b/api/src/utils/get-cache-key.ts @@ -2,12 +2,14 @@ import type { Request } from 'express'; import hash from 'object-hash'; import url from 'url'; import { getGraphqlQueryAndVariables } from './get-graphql-query-and-variables.js'; +import { version } from './package.js'; export function getCacheKey(req: Request): string { const path = url.parse(req.originalUrl).pathname; const isGraphQl = path?.startsWith('/graphql'); const info = { + version, user: req.accountability?.user || null, path, query: isGraphQl ? getGraphqlQueryAndVariables(req) : req.sanitizedQuery,