⏩ Local HTTPS for Express app (api) in Nx workspace
Tags: monorepo, nx, security, express
Published: 2020-10-08 15:45:52

Hey, welcome back in this post series where we will see how to setup a **full HTTPS development environment**. 

In this post, we will setup local HTTPS for Express app (api) in Nx workspace.

If you don't have generated your certificate with [mkcert](https://mkcert.dev), I recommand you read the first post of this series. → [link](https://dev.to/nightbr/full-https-ssl-development-environment-4dam)

## What is Nx?

![nx](https://dev-to-uploads.s3.amazonaws.com/i/1tj6eb5sgw977llxq4zh.png)

**[Nx](https://nx.dev/)** is a set of extensible dev tools for monorepos, which helps you manage your projects at any scale. It provides great integration with major framework such as Angular, React, Nestframework, Express, ionic, ...

💡 **Nx** use the `angular-cli` under the hood!

## Setting up the project workspace

Creating a new empty workspace

```bash
$ npx create-nx-workspace
npx : 179 installé(s) en 7.547s
? Workspace name (e.g., org name)     myorg
? What to create in the new workspace empty             [an empty workspace with a layout tha
t works best for building apps]
? CLI to power the Nx workspace       Nx           [Recommended for all applications (React, 
Node, etc..)]
...
```

*🗒️ If you already have an Nx workspace, you can skip these steps.*

Then, we will install the Express schematics:

```bash
npm install -D @nrwl/express
```

Now, we will generate a new Express application called `express-api` (change the name with your api name).

```bash
nx generate @nrwl/express:application --name=express-api
```

Start serving your app with `nx serve express-api` 🎉

![http](https://dev-to-uploads.s3.amazonaws.com/i/f4rfwidkfl8s8zjkfgt8.png)

🗒️ Look at the Express Nx plugin documentation to see more options → [here](https://nx.dev/latest/node/plugins/express/overview)

## Setting up HTTPS

From the first post of this series, I will assume that you have generated your certificate at location `myorg/dev-stack/certs/local-cert.pem` & `myorg/dev-stack/certs/local-key.pem`. Don't hesitate to go back to the first post to use mkcert and generate your certificate.

We will edit the express server to handle HTTPS requests.

Open and edit `myorg/apps/express-api/src/main.ts`

```tsx
import * as express from 'express';
import * as https from 'https';
import * as fs from 'fs';
import * as path from 'path';

const app = express();

app.get('/api', (req, res) => {
  res.send({ message: 'Welcome to express-api!' });
});

const port = Number(process.env.PORT) || 3333;
const hostname = process.env.HOSTNAME || 'localhost';
const ssl = process.env.SSL === 'true' ? true : false;
let server = null;

if (ssl) {
  const keyPath = process.env.SSL_KEY_PATH || '';
  const certPath = process.env.SSL_CERT_PATH || '';
  const httpsOptions = {
    key: fs.readFileSync(path.join(__dirname, keyPath)),
    cert: fs.readFileSync(path.join(__dirname, certPath)),
  };
  server = https.createServer(httpsOptions, app).listen(port, () => {
    console.log(`Listening at https://${hostname}:${port}/api`);
  });
} else {
  server = app.listen(port, () => {
    console.log(`Listening at http://${hostname}:${port}/api`);
  });
}

server.on('error', console.error);
```

We will now add `.local.env` with the configuration. 

```tsx
PORT=3333
HOSTNAME=dev.local
SSL=true
SSL_KEY_PATH="../../../dev-stack/certs/local-key.pem"
SSL_CERT_PATH="../../../dev-stack/certs/local-cert.pem"
```

🗒️ Here is some magic tricks done by Nx which will inject automatically `.local.env` when we will run the serve command. 

By default, Nx will load any environment variables you place in the following files:

1. `workspaceRoot/apps/my-app/.local.env`
2. `workspaceRoot/apps/my-app/.env`
3. `workspaceRoot/.local.env`
4. `workspaceRoot/.env`

You can see more on how Nx manage environment variables → [here](https://nx.dev/latest/angular/cli/overview#loading-environment-variables)

⚠️ IMPORTANT: the relative path to the certificate is from the dist folder (i.e. `dist/apps/express-api`).

Now serve the app with the new configuration:

```bash
$ nx serve express-api
```

You can open [https://dev.local:3333/api](https://dev.local:3333/api) which is secured with a valid certificate 🔐🎉


![https](https://dev-to-uploads.s3.amazonaws.com/i/fwolpbrt8jdn4dr7elvi.png)

![certificate](https://dev-to-uploads.s3.amazonaws.com/i/ep9pjwgbno3g8bzbh7tw.png)

Feel free to change any configuration in environment variables, but don't forget to regenerate a new certificate with mkcert of you change the domain name ⚠️

See you in the next post!

# Github repository

 {% github Nightbr/full-https-development-environment %}