From 5daf0796d1d56715ab64280d67b3a374bbce3cc0 Mon Sep 17 00:00:00 2001 From: Maciej Ziarkowski Date: Fri, 6 Sep 2019 19:13:45 +0100 Subject: [PATCH] Split server from frontend route --- app/src/frontendRoute.tsx | 110 ++++++++++++++++++++++++++++++++++++ app/src/server.tsx | 115 +------------------------------------- 2 files changed, 111 insertions(+), 114 deletions(-) create mode 100644 app/src/frontendRoute.tsx diff --git a/app/src/frontendRoute.tsx b/app/src/frontendRoute.tsx new file mode 100644 index 00000000..988eaf94 --- /dev/null +++ b/app/src/frontendRoute.tsx @@ -0,0 +1,110 @@ +import express from 'express'; +import React from 'react'; +import { StaticRouter } from 'react-router-dom'; + +import { renderToString } from 'react-dom/server'; +import serialize from 'serialize-javascript'; + +import App from './frontend/app'; + +import { parseBuildingURL } from './parse'; +import { getUserById } from './api/services/user'; +import { + getBuildingById, + getBuildingLikeById, + getBuildingUPRNsById +} from './api/services/building'; + + +// reference packed assets +const assets = require(process.env.RAZZLE_ASSETS_MANIFEST); + + +function frontendRoute(req: express.Request, res: express.Response) { + const context: any = {}; // TODO: remove any + const data: any = {}; // TODO: remove any + context.status = 200; + + const userId = req.session.user_id; + const buildingId = parseBuildingURL(req.url); + const isBuilding = (typeof (buildingId) !== 'undefined'); + if (isBuilding && isNaN(buildingId)) { + context.status = 404; + } + + Promise.all([ + userId ? getUserById(userId) : undefined, + isBuilding ? getBuildingById(buildingId) : undefined, + isBuilding ? getBuildingUPRNsById(buildingId) : undefined, + (isBuilding && userId) ? getBuildingLikeById(buildingId, userId) : false + ]).then(function ([user, building, uprns, buildingLike]) { + if (isBuilding && typeof (building) === 'undefined') { + context.status = 404; + } + data.user = user; + data.building = building; + data.building_like = buildingLike; + if (data.building != null) { + data.building.uprns = uprns; + } + renderHTML(context, data, req, res); + }).catch(error => { + console.error(error); + data.user = undefined; + data.building = undefined; + data.building_like = undefined; + context.status = 500; + renderHTML(context, data, req, res); + }); +} + +function renderHTML(context, data, req, res) { + const markup = renderToString( + + + + ); + + if (context.url) { + res.redirect(context.url); + } else { + res.status(context.status).send( + ` + + + + + Colouring London + + + ${ + assets.client.css + ? `` + : '' + } + ${ + process.env.NODE_ENV === 'production' + ? `` + : `` + } + + +
${markup}
+ + +` + ); + } +} + +export default frontendRoute; diff --git a/app/src/server.tsx b/app/src/server.tsx index 3d46d6ab..3ed45fe0 100644 --- a/app/src/server.tsx +++ b/app/src/server.tsx @@ -4,40 +4,25 @@ * - entry-point to shared React App * */ -import React from 'react'; -import { StaticRouter } from 'react-router-dom'; import express from 'express'; -import { renderToString } from 'react-dom/server'; -import serialize from 'serialize-javascript'; import session from 'express-session'; import pgConnect from 'connect-pg-simple'; -import App from './frontend/app'; import db from './db'; -import { getUserById } from './api/services/user'; -import { - getBuildingById, - getBuildingLikeById, - getBuildingUPRNsById -} from './api/services/building'; import tileserver from './tiles/tileserver'; import apiServer from './api/api'; -import { parseBuildingURL } from './parse'; +import frontendRoute from './frontendRoute'; // create server const server = express(); -// reference packed assets -const assets = require(process.env.RAZZLE_ASSETS_MANIFEST); - // disable header server.disable('x-powered-by'); // serve static files server.use(express.static(process.env.RAZZLE_PUBLIC_DIR)); - // handle user sessions const pgSession = pgConnect(session); const sess: any = { // TODO: remove any @@ -59,106 +44,8 @@ if (server.get('env') === 'production') { } server.use(session(sess)); -// handle HTML routes (server-side rendered React) -server.get('/*.html', frontendRoute); -server.get('/', frontendRoute); - -function frontendRoute(req, res) { - const context: any = {}; // TODO: remove any - const data: any = {}; // TODO: remove any - context.status = 200; - - const userId = req.session.user_id; - const buildingId = parseBuildingURL(req.url); - const isBuilding = (typeof (buildingId) !== 'undefined'); - if (isBuilding && isNaN(buildingId)) { - context.status = 404; - } - - Promise.all([ - userId ? getUserById(userId) : undefined, - isBuilding ? getBuildingById(buildingId) : undefined, - isBuilding ? getBuildingUPRNsById(buildingId) : undefined, - (isBuilding && userId) ? getBuildingLikeById(buildingId, userId) : false - ]).then(function (values) { - const user = values[0]; - const building = values[1]; - const uprns = values[2]; - const buildingLike = values[3]; - if (isBuilding && typeof (building) === 'undefined') { - context.status = 404 - } - data.user = user; - data.building = building; - data.building_like = buildingLike; - if (data.building != null) { - data.building.uprns = uprns; - } - renderHTML(context, data, req, res) - }).catch(error => { - console.error(error); - data.user = undefined; - data.building = undefined; - data.building_like = undefined; - context.status = 500; - renderHTML(context, data, req, res); - }); -} - -function renderHTML(context, data, req, res) { - const markup = renderToString( - - - - ); - - if (context.url) { - res.redirect(context.url); - } else { - res.status(context.status).send( - ` - - - - - Colouring London - - - ${ - assets.client.css - ? `` - : '' -} - ${ - process.env.NODE_ENV === 'production' - ? `` - : `` -} - - -
${markup}
- - -` - ); - } -} - server.use('/tiles', tileserver); - server.use('/api', apiServer); - -// use the frontend route for anything else - will presumably show the 404 page server.use(frontendRoute); export default server;