Skip to content

Commit 6d0e69f

Browse files
fix: Compress optimize tours request payload (#194)
- Add compression middleware to the backend - Change optimize tours endpoint to accept either a JSON body or a gzip-compressed JSON file - Compress optimize tours request bodies client-side in the frontend - Upgrade backend dependencies - Upgrade container image to Node 22 - Upgrade Terraform providers - Increase Cloud Run memory limit
1 parent fb99a7f commit 6d0e69f

File tree

24 files changed

+5605
-6329
lines changed

24 files changed

+5605
-6329
lines changed

.github/workflows/actions.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ jobs:
3232
steps:
3333
- uses: actions/checkout@v3
3434

35-
- name: Use Node.js v16 LTS
35+
- name: Use Node.js v22 LTS
3636
uses: actions/setup-node@v3
3737
with:
38-
node-version: '16'
38+
node-version: '22'
3939
cache: 'npm'
4040
cache-dependency-path: application/backend/package-lock.json
4141

@@ -56,10 +56,10 @@ jobs:
5656
steps:
5757
- uses: actions/checkout@v3
5858

59-
- name: Use Node.js v16 LTS
59+
- name: Use Node.js v22 LTS
6060
uses: actions/setup-node@v3
6161
with:
62-
node-version: '16'
62+
node-version: '22'
6363
cache: 'npm'
6464
cache-dependency-path: application/frontend/package-lock.json
6565

application/.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
16
1+
22

application/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# build frontend
2-
FROM node:16-alpine as build
2+
FROM node:22-alpine as build
33

44
WORKDIR /usr/src/app
55

@@ -17,7 +17,7 @@ ARG configuration=production
1717
RUN npm run build -- --output-path=./dist/out --configuration $configuration
1818

1919
# build backend
20-
FROM node:16-alpine
20+
FROM node:22-alpine
2121

2222
WORKDIR /usr/src/app
2323

application/backend/.eslintrc.json

Lines changed: 0 additions & 30 deletions
This file was deleted.

application/backend/app.ts

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ limitations under the License.
1717
import { promises as fs } from "fs";
1818

1919
import bodyParser from "body-parser";
20+
import compression from "compression";
2021
import cors from "cors";
2122
import express, { Response, Request } from "express";
22-
import expressPinoLogger from "express-pino-logger";
23-
import multer from "multer";
2423

2524
import { router as apiRoutes } from "./routes/api";
2625
import { router as optimizationRoutes } from "./routes/optimization";
@@ -30,15 +29,16 @@ import { log } from "./logging";
3029
export const app = express();
3130

3231
// logging
33-
app.use(
34-
expressPinoLogger({
35-
logger: log,
36-
})
37-
);
32+
app.use(log);
3833

3934
// headers
4035
app.disable("x-powered-by");
4136

37+
// compression
38+
app.use(
39+
compression()
40+
);
41+
4242
// cors
4343
app.use(
4444
cors({
@@ -48,22 +48,15 @@ app.use(
4848
})
4949
);
5050

51-
// multi-part form data
52-
app.use(
53-
multer({
54-
storage: multer.memoryStorage(),
55-
}).single("file")
56-
);
57-
5851
// body parser
59-
app.use(bodyParser.json({ limit: "50mb" }));
60-
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
52+
app.use(bodyParser.json({ limit: "1gb" }));
53+
app.use(bodyParser.urlencoded({ limit: "1gb", extended: true }));
6154

6255
/**
6356
* Readiness/liveness probe
6457
*/
6558
app.get("/healthz", async (req: Request, res: Response) => {
66-
log.debug("Health check");
59+
log.logger.debug("Health check");
6760
res.status(200).send("OK");
6861
});
6962

@@ -76,13 +69,13 @@ app.get("/config.json", async (req: Request, res: Response) => {
7669
// get config.json from angular app when proxied
7770
if (process.env.FRONTEND_PROXY) {
7871
try {
79-
const axios = (await import("axios")) as any;
72+
const axios = (await import("axios") as any);
8073
const response = await axios.get(
8174
process.env.FRONTEND_PROXY + "config.json"
8275
);
8376
config = response.data;
8477
} catch (err) {
85-
log.error(err);
78+
log.logger.error(err);
8679
}
8780
}
8881

@@ -92,7 +85,7 @@ app.get("/config.json", async (req: Request, res: Response) => {
9285
const data = await fs.readFile("public/config.json");
9386
config = JSON.parse(data.toString());
9487
} catch (err) {
95-
log.error(err);
88+
log.logger.error(err);
9689
return res.sendStatus(404);
9790
}
9891
}
@@ -122,7 +115,7 @@ app.get("/config.json", async (req: Request, res: Response) => {
122115

123116
res.status(200).send(config);
124117
} catch (err) {
125-
log.error(err);
118+
log.logger.error(err);
126119
return res.sendStatus(500);
127120
}
128121
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import eslint from '@eslint/js';
2+
import tseslint from 'typescript-eslint';
3+
4+
export default tseslint.config(
5+
[
6+
{
7+
ignores: [
8+
"node_modules/**",
9+
"lib/**",
10+
"**/*.js"
11+
],
12+
},
13+
eslint.configs.recommended,
14+
tseslint.configs.recommended,
15+
],
16+
{
17+
rules: {
18+
"@typescript-eslint/no-explicit-any": "warn"
19+
}
20+
}
21+
);

application/backend/logging.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import { pino, Logger } from "pino";
17+
import { pinoHttp, HttpLogger } from "pino-http";
1818

1919
// map pino level to google cloud logging severity
2020
const levelToGoogleSeverity: { [level: string]: string } = {
@@ -55,9 +55,9 @@ if (!process.env.LOG_FORMAT || process.env.LOG_FORMAT === "google") {
5555

5656
return object;
5757
},
58-
log: (o: any) => {
58+
log: (o: Record<string, unknown>) => {
5959
const { err, ...reshaped } = o;
60-
if (err) {
60+
if (err instanceof Error) {
6161
reshaped.stack_trace = err.stack;
6262
}
6363
return { serviceContext, ...reshaped };
@@ -82,6 +82,6 @@ else if (process.env.LOG_FORMAT === "pretty") {
8282
);
8383
}
8484

85-
const p = pino(options);
85+
const p = pinoHttp(options);
8686

87-
export const log: Logger = p;
87+
export const log: HttpLogger = p;

application/backend/openapi.yaml

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
openapi: 3.0.3
1+
openapi: 3.1.1
22
info:
33
title: Fleet Routing App - Backend
44
version: 4.0.0
@@ -9,6 +9,10 @@ paths:
99
Static web content.
1010
Paths not matched by other API routes are directed to static file serving middleware
1111
to deliver the frontend application.
12+
responses:
13+
200:
14+
description:
15+
OK
1216

1317
/healthz:
1418
get:
@@ -29,11 +33,19 @@ paths:
2933
description:
3034
A [`google.cloud.optimization.v1.IOptimizeToursRequest`](https://cloud.google.com/optimization/docs/reference/rpc/google.cloud.optimization.v1#optimizetoursrequest),
3135
with the `parent` property omitted (to be added by the backend).
36+
3237
required: true
3338
content:
3439
application/json:
3540
schema:
36-
type: array
41+
type: object
42+
multipart/form-data:
43+
schema:
44+
type: object
45+
properties:
46+
file:
47+
format: binary
48+
description: A gzip-compressed JSON file containing the IOptimizeToursRequest data
3749
responses:
3850
200:
3951
description:
@@ -90,22 +102,21 @@ paths:
90102
schema:
91103
type: array
92104
items:
93-
schema:
94-
type: object
95-
properties:
96-
name:
97-
type: string
98-
pageToken:
99-
type: object
100-
properties:
101-
prefix:
102-
type: string
103-
maxResults:
104-
type: integer
105-
autoPaginate:
106-
type: boolean
107-
pageToken:
108-
type: string
105+
type: object
106+
properties:
107+
name:
108+
type: string
109+
pageToken:
110+
type: object
111+
properties:
112+
prefix:
113+
type: string
114+
maxResults:
115+
type: integer
116+
autoPaginate:
117+
type: boolean
118+
pageToken:
119+
type: string
109120
required: ['name']
110121
example:
111122
- name: "2020-10-23/0-vehicles-10-shipments-dayton.request.json"
@@ -259,22 +270,21 @@ paths:
259270
schema:
260271
type: array
261272
items:
262-
schema:
263-
type: object
264-
properties:
265-
name:
266-
type: string
267-
pageToken:
268-
type: object
269-
properties:
270-
prefix:
271-
type: string
272-
maxResults:
273-
type: integer
274-
autoPaginate:
275-
type: boolean
276-
pageToken:
277-
type: string
273+
type: object
274+
properties:
275+
name:
276+
type: string
277+
pageToken:
278+
type: object
279+
properties:
280+
prefix:
281+
type: string
282+
maxResults:
283+
type: integer
284+
autoPaginate:
285+
type: boolean
286+
pageToken:
287+
type: string
278288
example:
279289
- name: "2020-10-23/0-vehicles-10-shipments-dayton.request.json"
280290
pageToken:

0 commit comments

Comments
 (0)