Overview
NX is a great tool to manage Mono-repos. I’ve been using it for near on 5 years in my professional life and around about the same on a number of side projects.
One of the first things I set up in any new mono-repo is the proxying of API requests through the front-end to the API running in parallel.
With NX this is super easy and makes life simple as you only have to run one command and get both stacks running all at the same time.
In this example I’ll be using NestJS as the Back-end and Angular as the front-end as it is my preferred stack.
Getting Started with NX
Install NX and set up your two applications. I always start with my frontend application, so in this case. Angular:
npx create-nx-workspace
and select angular
Now we are looking at adding NestJs which is my Node Framework of choice.
First add it to NX
nx add @nx/nest
Now add a new application
nx g @nx/nest:app apps/my-nest-app
Proxy in frontend serve
All of our proxy is setting up on the frontend application, the backend application (as long as it builds and serves individually) will remain the same.
We want to add a proxy config into our frontend application, this is added to project.json
under the serve
command in the frontend folder.
"options": {
"proxyConfig": "apps/frontend/proxy.conf.json"
}
As you can see this is pointing at a proxy config which looks like this
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
This is one of the settings to look at out base Backend (NestJs) application and proxy it to the /api route.
Note: The port here needs to point at the port your backend API is serving from.
New Serve Command (replaces default)
We now need to create a new a new serve command that will run both applications at the same time. This is super handy to mean we can run one simple command, both applications in parallel and we watch both directories.
"serve-with-services": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "nx serve api"
},
{
"command": "nx serve frontend"
}
],
"parallel": true
}
},
New (updated) run Script in Package.json
Now we have our new “serve-with-services” command for our frontend app, we want to make this our main serve command in our package.json
"start": "nx serve-with-services frontend"
Testing what we have
With everything set up, we should now just be able to run:
npm run start
This should run both apps, with the proxy working. If it doesn’t there might be a bit of debugging to do.
Environment Variables
Now we can run the applications in parallel we want to create an environment file, so that when we build and depoy to production it will swap out your API route so that you can point it wherever you want.
In my stack I like to run my APIs on CloudRun in GCP (Google Cloud) and run my frontend over in AWS, so i route over the internet, that’s why i run an ApiHost variable to swap out the local and deployed version.
in the frontend application we need to create an environments
file.
These files are created in a folder called environments
inside the app
folder
Non-Production Environment File
export const environment {
production: false;
apiHost: '/api'
}
Production
export const environment = {
production: true,
apiHost: '//someplace.com/api',
}
Now do the file replacement in the config This goes in the project.json
under the configurations
object.
"production": {
"fileReplacements": [
{
"replace": "apps/frontend/src/app/environments/environment.ts",
"with": "apps/frontend/src/app/environments/environment.prod.ts"
}
]
}
Now when you deploy (or run a production build) you will be swapping out the non-production UriHost with the production, allowing you to point at your production infra without having to think about it.
Summary
After all this you can do a command to run both and you will proxy all the API requests in the frontend and be able to hit them at “/api”. Both directories will get watched for changes as well which makes it easy to build out and develop
This makes developing a full stack app with NX a bunch easier and quicker and should simplify
Any questions shoot me an email at [[email protected]]