The documentation (https://angular.dev/guide/ssr) states that:
Angular CLI will scaffold an initial server implementation focused on server-side rendering your Angular application. This server can be extended to support other features such as API routes, redirects, static assets, and more. See Express documentation for more details.
And this is fine, but when you run angular (ng serve
) the server (server.ts
) is not even used so none of our API routes are registered.
What is the recommended approach here? Should we spin our own express.js server for API routes in development?
I just ran into this problem myself. The solution I came up with was to (1) create a barebones copy of the server that runs on a different local port, (2) set up ng serve
to proxy requests to my API over to that second server, and (3) change my start
command over to concurrently run both of these.
I kept all of my API-specific code in /src/api
, so this file is /src/api/dev-server.ts
:
import express from "express";
import {configureAPI} from "./index";
// This is ONLY used to start the server in development mode; do not use in production, and do not add any special
// handling logic in here.
const server = express();
server.use('/api', configureAPI(express.Router()));
// configureAPI takes a router, adds all my routes, then returns it; do whatever
// server config here you want
const port = process.env['API_PORT'] || 3000;
server.listen(port, () => {
console.log(`Dev API server listening on port ${port}`);
});
I then set up nodemon
with this nodemon.json
(you'll need to npm install -D nodemon ts-node
):
{
"ignore": ["**/*.test.ts", "**/*.spec.ts", "node_modules"],
"watch": ["src/api"],
"exec": "ts-node src/api/dev-server.ts",
"ext": "ts"
}
So now, if I run nodemon
, my API starts up on port 3000.
ng serve
proxyingThis is actually built in! Make a new file, proxy.conf.json
:
{
"/api":
{
"target": "http://localhost:3000",
"secure": false,
"changeOrigin": true,
"cookieDomainRewrite": "localhost:4200"
}
}
Now if you run ng serve --proxy-config proxy.conf.json
, it'll start up your server as normal, but any requests to /api
will be sent to the API server running over on port 3000.
First, npm install -D concurrently
.
Here's the relevant scripts in my package.json
:
{
"scripts": {
"start": "concurrently 'npm:start:angular' 'npm:start:dev-server'",
"start:angular": "ng serve --proxy-config proxy.conf.json",
"start:dev-server": "nodemon",
}
}
Now, just npm start
, and it all just works :D