app-backend: update router to use static assets store and new cache headers

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-12-29 16:58:01 +01:00
parent 7261b76935
commit 729b188045
2 changed files with 45 additions and 5 deletions
@@ -81,7 +81,7 @@ describe('createRouter', () => {
'returns %s with default Cache-Control header',
async file => {
const response = await request(app).get(file);
expect(response.header['cache-control']).toBe('public, max-age=0');
expect(response.header['cache-control']).toBe('public, max-age=1209600');
},
);
});
+44 -4
View File
@@ -14,7 +14,11 @@
* limitations under the License.
*/
import { notFoundHandler, resolvePackagePath } from '@backstage/backend-common';
import {
notFoundHandler,
PluginDatabaseManager,
resolvePackagePath,
} from '@backstage/backend-common';
import { Config } from '@backstage/config';
import helmet from 'helmet';
import express from 'express';
@@ -23,6 +27,15 @@ import fs from 'fs-extra';
import { resolve as resolvePath } from 'path';
import { Logger } from 'winston';
import { injectConfig, readConfigs } from '../lib/config';
import {
StaticAssetsStore,
findStaticAssets,
createStaticAssetsStoreMiddleware,
} from '../lib/assets';
import {
CACHE_CONTROL_MAX_CACHE,
CACHE_CONTROL_NO_CACHE,
} from '../lib/headers';
// express uses mime v1 while we only have types for mime v2
type Mime = { lookup(arg0: string): string };
@@ -31,6 +44,12 @@ export interface RouterOptions {
config: Config;
logger: Logger;
/**
* The plugin database manager which of provided, the app-backend will use to cache previously
* deployed static assets.
*/
database?: PluginDatabaseManager;
/**
* The name of the app package that content should be served from. The same app package should be
* added as a dependency to the backend package in order for it to be accessible at runtime.
@@ -94,7 +113,28 @@ export async function createRouter(
// Use a separate router for static content so that a fallback can be provided by backend
const staticRouter = Router();
staticRouter.use(express.static(resolvePath(appDistDir, 'static')));
staticRouter.use(
express.static(resolvePath(appDistDir, 'static'), {
setHeaders: res => {
res.setHeader('Cache-Control', CACHE_CONTROL_MAX_CACHE);
},
}),
);
if (options.database) {
const store = await StaticAssetsStore.create({
logger,
database: await options.database.getClient(),
});
const assets = await findStaticAssets(staticDir);
await store.storeAssets(assets);
// Remove any assets that are older than 7 days
await store.trimAssets({ maxAgeSeconds: 60 * 60 * 24 * 7 });
staticRouter.use(createStaticAssetsStoreMiddleware(store));
}
if (staticFallbackHandler) {
staticRouter.use(staticFallbackHandler);
}
@@ -109,7 +149,7 @@ export async function createRouter(
if (
(express.static.mime as unknown as Mime).lookup(path) === 'text/html'
) {
res.setHeader('Cache-Control', 'no-store, max-age=0');
res.setHeader('Cache-Control', CACHE_CONTROL_NO_CACHE);
}
},
}),
@@ -119,7 +159,7 @@ export async function createRouter(
headers: {
// The Cache-Control header instructs the browser to not cache the index.html since it might
// link to static assets from recently deployed versions.
'cache-control': 'no-store, max-age=0',
'cache-control': CACHE_CONTROL_NO_CACHE,
},
});
});