developers

Developing a Secure API with NestJS: Getting Started

Learn how to use NestJS, a Node.js framework powered by TypeScript, to build a secure API.

Oct 29, 20194 min read

We tested this tutorial using NestJS
v7.0.0
, Node.js
v10.16.3
, and npm
v6.9.0
.

NestJS is known as an architecture framework for Node.js, but what is an "architecture framework"? Is this yet another buzzword? Nope! It's legit.

NestJS may feel like the Laravel or Rails of the Node.js world as it favors convention over configuration. It offers you opinionated guidelines and code conventions. So, instead of worrying about naming or organizing files and folders, you can focus on building features for your product.

On its mission to remove the guesswork out of API development, NestJS offers first-class support for TypeScript to add static type-checking to your projects. Your API code becomes self-documented: you'll know if a method expects a

string
, a
number
, a
Cat
, or a
TwitterHotTake
.

Today, you'll learn how to build a secure API with NestJS and create your own opinion on the framework.

What You Will Build

Your goal is to create and secure a feature-complete API, which lets clients perform data operations on a mock restaurant menu. To test, consume, and even try to hack your API, you'll use a demo client called "WHATABYTE Dashboard".

WHATBYTE Dashboard

WHATBYTE Dashboard menu item

This dashboard is inspired by the sleek web player from Spotify.

We tested this tutorial using Node.js

v10.16.3
and NPM
v6.9.0
. If you need to install any of them, follow the instructions provided by the Node.js Foundation for your operating system.

For simplicity, you'll store data in-memory and not in an external database.

For security, you'll limit API access by following these business rules:

  • Anyone can read data.

  • Only users with a

    menu-admin
    role are authorized to write data: create, update, or delete menu items.

Get Started with NestJS

NestJS offers a powerful CLI tool to build your application. To generate a new project, use

npx
to run the NestJS CLI without installing it globally in your system:

npx @nestjs/cli new nest-restaurant-api

The

npx
command is available with
npm v5.2.0
and higher.

The CLI asks you to choose a package manager,

npm
or
yarn
, and proceeds to install project dependencies using your selection. To follow this tutorial, choose
npm
.

Using the NestJS CLI to scaffold a new project

Once the installation is complete, you get a directory called

nest-restaurant-api
. Navigate to this directory:

# move into the project directory
cd nest-restaurant-api

Clean Up the NestJS Starter

For simplicity, you won't be writing any tests in this tutorial. However, it would be best if you wrote robust tests for any production-ready application. As such, delete the

test
directory and the
src/app.controller.spec.ts
file from your project:

rm -rf test/
rm src/app.controller.spec.ts

Refer to the NestJS Testing documentation for details on how to perform automated tests.

After that, delete the files defining

AppController
and
AppService
:

rm src/app.controller.ts src/app.service.ts

Deleting these files breaks

AppModule
as it depends on
AppController
and
AppService
. To fix that, open the project in your preferred IDE and update
src/app.module.ts
as follows:

// src/app.module.ts

import { Module } from '@nestjs/common';

@Module({
  imports: [],
  controllers: [],
  providers: [],
})
export class AppModule {}

Use Environmental Variables

src/main.ts
is the entry point of your application. However, this file uses a hard-coded port number to listen for incoming requests,
3000
, making your application less adaptable to different development and production environments.

To fix that, you can store environmental variables locally in a

.env
file and use a package like
dotenv
to load them into the global variable
process.env
.

To start, install

dotenv
in your project:

npm i dotenv

Then, create this hidden file under the root project directory:

touch .env

Open

.env
and populate it with the following data:

PORT=7000

To attach data from

.env
into
process.env
, you need to call the
dotenv.config()
method at the top of each module that needs that data. As such, update
src/main.ts
to replace the hard-coded port number with
process.env.PORT
as follows:

// src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';

dotenv.config();

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT);
}
bootstrap();

Now when your application runs, it listens for requests on whatever the value of

process.env.PORT
may be —
7000
in this case.

⚠️ Caution:

.env
may eventually contain sensitive information, such as API keys or secrets. Add it to
.gitignore
before committing code to version control.

Next Step: I am ready to start building my NestJS appI ran into an issue

@nestframework is an architecture framework for @nodejs. Learn how to create scalable and maintainable server-side apps with it.

Tweet This