fix: compatability check header shown if client is using cached responses (@fehmer) (#6602)

If frontend and backend are deployed with a new COMPATABILITY_CHECK
header frontend might show the backend version is lower because of the
http header of a cached response.

Adding the COMPATABILITY_CHECK version as part of the etag fixes this.
This commit is contained in:
Christian Fehmer 2025-05-27 16:59:49 +02:00 committed by GitHub
parent 093a17b15a
commit d6ae7cf7c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 0 deletions

View file

@ -38,6 +38,7 @@
"cron": "2.3.0",
"date-fns": "3.6.0",
"dotenv": "16.4.5",
"etag": "1.8.1",
"express": "4.21.1",
"express-rate-limit": "7.4.0",
"firebase-admin": "12.0.0",

View file

@ -10,6 +10,9 @@ import {
} from "./middlewares/rate-limit";
import { compatibilityCheckMiddleware } from "./middlewares/compatibilityCheck";
import { COMPATIBILITY_CHECK_HEADER } from "@monkeytype/contracts";
import { createETagGenerator } from "./utils/etag";
const etagFn = createETagGenerator({ weak: true });
function buildApp(): express.Application {
const app = express();
@ -27,6 +30,8 @@ function buildApp(): express.Application {
app.use(badAuthRateLimiterHandler);
app.use(rootRateLimiter);
app.set("etag", etagFn);
addApiRoutes(app);
app.use(errorHandlingMiddleware);

25
backend/src/utils/etag.ts Normal file
View file

@ -0,0 +1,25 @@
import { COMPATIBILITY_CHECK } from "@monkeytype/contracts";
import { default as etag } from "etag";
/**
* create etag generator, based on the express implementation https://github.com/expressjs/express/blob/9f4dbe3a1332cd883069ba9b73a9eed99234cfc7/lib/utils.js#L247
* Adds the api COMPATIBILITY_CHECK version in front of the etag.
* @param options
* @returns
*/
export function createETagGenerator(options: {
weak: boolean;
}): (body: Buffer | string, encoding: BufferEncoding | undefined) => string {
return function generateETag(body, encoding) {
const buf = !Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const generatedTag: string = etag(buf, options);
//custom code to add the version number
if (generatedTag.startsWith("W/")) {
return `W/"V${COMPATIBILITY_CHECK}-${generatedTag.slice(3)}`;
}
return `"V${COMPATIBILITY_CHECK}-${generatedTag.slice(1)}`;
};
}

3
pnpm-lock.yaml generated
View file

@ -95,6 +95,9 @@ importers:
dotenv:
specifier: 16.4.5
version: 16.4.5
etag:
specifier: 1.8.1
version: 1.8.1
express:
specifier: 4.21.1
version: 4.21.1