Angular and the REST with Nest.js
Tags: angular
Published: 2019-07-30 16:08:39

This week I continue writing on the series of [Angular and the REST](https://dev.to/thisdotmedia/angular-and-the-rest-4ho7) by using Angular for the front-end and [Nest.js](https://nestjs.com/), a Node app, for the backend. In addition, the backend app will be connecting to a [PostgreSQL](https://www.postgresql.org/) database instance running on top of a [Docker](https://www.docker.com/) container. 

The third installment of this series will cover the Nrwl/Nx project to build a monorepo containing an Angular app, Nest.js app and a set of libraries to serve those apps. The front-end app will implement CRUD operations to allow an anonymous user to manage and track movies.

In the next installment of this series, we will continue building to support authentication in the app using JWT (JSON Web Tokens) to restrict access to managing and tracking movies to authenticated users only.

In case you haven't read the previous two installments, here is a quick reminder of what we are going to build. 

I start building the Angular app to track movies that I've watched and will be watching in the future. The Angular app allows me to perform all CRUD, Create Read Update and Delete, operations on the movies. From the backend side, I will build a Nest.js Web API. For the time being, it will provide a RESTful Endpoint to perform all the CRUD operations on movies and connect to PostgreSQL database. 

> If you are new to Nest.js I recommend reading my other series of articles. The series follows a Step-by-Step guide teaching the Nest.js framework starting with the basics to more advanced topics. [Nest.js Step-by-Step](https://www.codemag.com/Article/1907081/Nest.js-Step-by-Step).

For this article and the coming one, I assume you have a basic knowledge of Nrwl/Nx, Nest.js and Angular. Also, I will be sharing some great resources for a reference if need be.

Let's start creating the monorepo workspace using Nrwl/Nx extensions.

The source code for this monorepo workspace can be found on this GitHub [repo](https://github.com/bhaidar/movie-tracker/tree/develop).

## Building the Monorepo with Nrwl/Nx workspace 
In brief, Nrwl/Nx is defined by the tooling it provides:
- It contains schematics to help with generating code in the projects to ensure consistency.
- It contains tools to help with enforcing linting rules and code formatting.
- It allows you to visualize dependencies between apps and libraries within a repository.
- It allows commands to be executed against code changes: any uncommitted changes, comparison between two specific git commits, comparison against another branch, etc. These commands can test, lint, etc. only the affected files, saving us a lot of time by avoiding files that were not affected by our changes.
- It includes utilities to help with race conditions in Angular applications.

> I suggest you read the book [Enterprise Angular: Monorepo Patterns](https://blog.nrwl.io/our-new-angular-book-for-2019-and-more-7876898ea027) for an in depth knowledge on Nrwl/Nx.

> To get started learning and using Nrwl/Nx the best resource to read is their [official documentation and tutorials](https://nx.dev/angular/getting-started/what-is-nx).
 
### What is an Nx workspace?
An Nx workspace is a folder created using Nx. The folder consists of a single git repository, with folders for apps and libs; along with some scaffolding to help with building, linting and testing.

### Create the Movie Tracker Nx Workspace
Let's follow the steps below to create the **Movie Tracker** workspace structure.

**Step 1**
Start by installing the latest releases of the Angular CLI and Nrwl/Nx Schematics. Run the following command:
`yarn global add @angular/cli @nrwl/schematics`

The command installs the latest releases globally of both Angular CLI and Nrwl/Schematics.

**Step 2**
Let's create the Movie Tracker workspace by running this command:
`yarn create nx-workspace mt --directory=movie-tracker`

This command downloads and installs the latest `create-nx-workspace` CLI NPM package. The CLI then prompts you with a set of questions allowing you to customize your Nx workspace.

I've chosen the following:
- `Which stylesheet format would you like to use?` **SASS (.scss)**
- `What to create in the new workspace?` **empty** 

The **empty** answer instructs the `create-nx-workspace` CLI to create an empty workspace. I will show you how we can control what apps and libraries to create shortly.

Right after answering these two questions, the CLI generates a new workspace for you.

![Empty Nx workspace](https://thepracticaldev.s3.amazonaws.com/i/7df927458fjg6o6597kq.PNG)

The **apps* and **libs** folders are empty. We will fill them soon.

Notice the `nx.json` file. This file is Nx specific to track all projects created in the workspace.

{% gist https://gist.github.com/bhaidar/b9a03db96dc5d17af4a7bc9077cd578f %}

The **npmScope** is used later by Nx-workspace to add a path alias, in the root `tsconfig.json` file, for each and every library created in the workspace. This makes import statements simpler and less crowded.

**Step 3**
Let's add the `movietracker` Angular application.

Start by enabling the `create-nx-workspace` CLI with the Nrwl/Angular schematics by running the following command in a terminal window:
`ng add @nrwl/angular --defaults`

Next, you can create your first Angular app by running this command:
`ng g @nrwl/angular:application movietracker --prefix=mt`
 
The command scaffolds a new Angular app inside the `apps` folder. In case you want to nest the application inside a folder, you can simply pass a directory name by using the parameter `--directory`.

The application created above has a prefix of `mt`.

**Step 4**
Let's add a few libraries needed by the Angular app.

Run the following command to generate the `movies` library under `libs\movietracker` folder. Notice the name of the subfolder `movietracker` resembles that of the Angular app. This way, all the libs related to the Angular app `movietracker` are placed in one centralized place grouped by the app name.
`ng g @nrwl/angular:lib movies --directory=movietracker`

This command creates a new library with the `MovietrackerMovies` module.The module will contain all the components related to managing movies.

Run the command to generate the `ui` library under `libs\movietracker` folder:
`ng g @nrwl/angular:lib ui --directory=movietracker`

The command creates a new library with the `MovietrackerUi` module. This module will contain all the components that are used by `movietracker` libs. The module declares UI components and exports them in return to be accessible outside its boundaries. In addition, this module imports and re-exports the Angular Material modules to be accessible in other modules.

The next command generates the `core` library under `libs\movietracker` folder:
`ng g @nrwl/angular:lib core --directory=movietracker`

This creates a new library with the `MovietrackerCore` module. The core module will contain shared helper classes. In addition, it imports and re-exports the `MovietrackerUi` module and other standard Angular modules that are needed in the Angular app. This way, the Angular app will import this module statically so that all UI components and shared helper classes, will be available at the Angular app root level.

**Step 5**
Let's create the `api-services` shared library that will eventually contain all the Angular Services needed by the app to connect to the backend.

Now run the command to generate the `api-services` library under `libs` folder:
`ng g @nrwl/workspace:lib api-services`

This will create a new library without a module. Later we will add Angular Services decorated with:

```typescript
@Injectable({
  providedIn: 'root'
})
```

This way, all services added to this library will be available at the root Angular app.

**Step 6**
Finally, let's create the `interfaces`shared library that will contain all interfaces for all modules needed by the application.

Run the command to generate the `interfaces` library under `libs` folder:
`ng g @nrwl/workspace:lib interfaces`

The command creates a new library without a module. Later, we fill this library with all models we need in the application.

**Step 7**
The last step. We will create the Nest.js application. 

Start by enabling the `create-nx-workspace` CLI with the Nrwl/Nest schematics by running the following:
`ng add @nrwl/nest`

Next, you can create your first Nest.js app by running this command:
`ng g @nrwl/nest:app api --frontendProject=movietracker`

The command creates a new Nest.js app under the folder `apps`. The `frontendProject` parameter is required so the CLI can configure the Angular app with a `proxy.conf` so all calls to the backend are redirected to the correct port where the Nest.js app is running.

> You may read more about [Proxying a Backend Server](https://angular.io/guide/build#proxying-to-a-backend-server) on the Angular website.

### Update `tsconfig.json` files
I've tweaked the `tsconfig.json` files located in the root of the workspace, the Angular app and the Nest.js app. The changes mainly direct the output of the applications into a single `/dist` location to make it easier for deployment later on.

Replace the contents of the `tsconfig.json` file located at the root of the workspace as follows:

{% gist https://gist.github.com/bhaidar/ab803ee7e8fe4e2a5de482ccbc591408 %}

Replace the contents of the `tsconfig.app.json` file located inside the Angular app as follows:

{% gist https://gist.github.com/bhaidar/322e5015e77583b1dc8d52232a24b2cc %}

Replace the contents of the `tsconfig.json` file located inside the Nest.js app as follows:

{% gist https://gist.github.com/bhaidar/3b6bafddb385fe55fa82ae859d1528ad %}

Now we are ready to start coding our apps!

## Building the Nest.js Web API app
In this section I'll be building the functionality for the Web API. In addition, we will setup a PostgreSQL database instance running on top of Docker container.

First things first. Let's build a PostgreSQL database instance running on top of Docker.

**Step 1**
Create a `docker-compose.yaml` file at the root of the workspace with the following content:

{% gist https://gist.github.com/bhaidar/fff34c0cc7acf7dec8c64a32f99a8522 %}

The file configures a PostgreSQL database service running the `postgres:10.7` version. In addition, it defines a volume mapped to a physical location inside the app, so we can feed in a bash script that runs the first time the container is created and started. 

The bash script is located under `.\db\init.db\init-users-db.sh` folder and contains the following:

{% gist https://gist.github.com/bhaidar/5318cf0a525638a4d911d37f71dd6675 %}

The script creates a new database and a database user. It also makes the user a `SUPERUSER` on the database. Remember, this is only used while in the development stage and not in production, so we are okay with this setup!

Let's add a new NPM script to the `package.json` file to make it easy to run the Docker container:

```json
"run:services": "docker-compose up && exit 0",
"stop:services": "docker-compose kill"
```

The first script is used to run the Docker container. The second is used to stop the container.

Open a terminal window and run the command to make sure the Docker container is up and running:
`yarn run run:services`

**Step 2**
Next, we will install and configure **TypeORM** to use inside our Nest.js application. 

> TypeORM is a JavaScript ORM that is supported by Nest.js. You can read more about TypeORM by checking their [official documentation website](https://typeorm.io/#/).

The next command:
`yarn add typeorm pg @nestjs/typeorm`

The command installs the `typeorm` library, the `pg` client used internally by TypeORM to connect to a PostgreSQL database and `@nestjs/typeorm` module provided by Nest.js to integrate with TypeORM.

To configure TypeORM, create an `ormconfig.json` file at the root of the workspace with:

{% gist https://gist.github.com/bhaidar/6163be7bcedce5d0cd8c4792fa405566 %}

This configuration file contains the connection string named `development` that will be used by TypeORM to connect to the database.

I've configured TypeORM to auto-sync everytime we run the Nest.js application to migrate the database structure if need be. When you move to production, you should definitely turn this setting off and use **migrations**.

**Step 3**
Let's start coding the Nest.js Web API app.

Add a new `movietracker` module under the path `apps\api\src\app\movietracker` with the following:

{% gist https://gist.github.com/bhaidar/c32fba84d381ecbc57584878d47d4665 %}

This module configures the `TypeOrmModule` with the entities used within it. In this case it is the `MovieEntity`. Also, it defines a `MovieTrackerController` and `MovieTrackerService`.

The `TypeOrmModule.forFeature([])` method configures the `TypeOrmModule` with the entities used in this module. By passing the list of entities, in our case there is only one entity, we guarantee that each entity will have its own `Repository<TEntity>` instance ready to be injected and used by the services as you will see shortly.

**Step 4**
Add the `MovieEntity` class under the path `apps\api\src\app\movietracker\entity\movie.entity.ts` with the following content:

{% gist https://gist.github.com/bhaidar/9b42be62263c72d7c72c95abf603439b %}

We annotate the Movie class with TypeORM decorators that will be used eventually by the TypeORM engine to generate the tables inside the database.

One important thing to note here, is the `Movie Id` is annotated with `PrimaryGenerationColumn('uuid')`. TypeORM will generate a new `UUID` value for each Movie added to the database.

> You can learn more about TypeORM decorators by visiting their [Decorator Reference](https://github.com/typeorm/typeorm/blob/master/docs/decorator-reference.md).

**Step 5**
Let's create the `MovieTrackerService` under the path `apps\api\src\app\movietracker\movietracker.service.ts`. This service contains methods to handle searching for movies, adding a new movie, editing an existing movie and deleting a movie.

The service injects the `Repository<MovieEntity>` instance via it's constructor. 

```typescript
  constructor(
    @InjectRepository(MovieEntity)
    private readonly movieTrackerRepo: Repository<MovieEntity>
  ) {}
```

Nest.js has a built-in dependency injection system that supports IoC (Inversion of Control). We use the `@InjectRepository()` decorator whenever we inject a custom provider, which is the case here. The `@nestjs/typeorm` integration module defines the repositories for the entities configured at the `MovieTrakerModule` as we will see shortly.

> Read more about custom providers at the [official documentation website](https://docs.nestjs.com/fundamentals/custom-providers).

The `searchMovies(term: string)` method is defined as follows:

{% gist https://gist.github.com/bhaidar/c1f9fbe57411517ed0adc3a72616c63d %}

The method uses the underlying repository to find and return all movies whose `title` or `genre` contains the search term passed into the method.

The `addMovie(addMovieDto: AddMovieDto)` method is defined as follows:

{% gist https://gist.github.com/bhaidar/dc21f645f6943230c1a296300e3f124b %}

This method receives as input an object of type `AddMovieDto`. We will shortly look at DTOs (Data Transfer Object).

The method creates and returns a new movie stored in the database with the Movie Id populated. 

Notice the movie returns a `MovieDto` rather than a `MovieEntity`. This is a basic concept when dealing with backend apps. You don't need to return a full Entity object. Sometimes you want to hide some fields and not return them to the front-end. That's why we define DTOs with exactly the fields we want to return back to the client-side app.

The `updateMovie(id: string, movieDto: MovieDto)` method is defined as:

{% gist https://gist.github.com/bhaidar/528d58d7a602e8673c424c37330a7b64 %}

The method starts by finding a movie stored in the database, updates it and returns the newly updated movie in the form of a `MovieDto`.
The `deleteMovie(id: string)` method is defined as follows:

{% gist https://gist.github.com/bhaidar/8b9d3f96f83e803ff6eddc1883b0d64a %}.

The method starts by finding a movie stored in the database, deletes the movie and returns the deleted movie in the form of a `MovieDto`.

**Step 6**
Let's add a set of DTO (Data Transfer Objects). The front-end app will use these objects when communicating with the backend app. Whether to send data or receive data, the front-end app always uses these DTOs and never deals with Entities. Entities belong to the backend app only.

The `movie.dto` object:

{% gist https://gist.github.com/bhaidar/f3d6f2b1d35cdcd89f5ffc11ea0ebbaf %}

This object is annotated by validation decorators defined by `class-validator` and `class-transformer` libraries.

At this stage, you need to install both libraries into your application by running this command:
`yarn add class-transformer class-validator`

The annotations are self-explanatory and are used to enforce some validation rules to the data received from the front-end app.

Nest.js defines a `ValidationPipe` pipe that validates objects with such annotations. Soon you will see where we configure this pipe. 

> You can read more about Nest.js Pipes by checking the [official documentation website](https://docs.nestjs.com/pipes).

You may access the rest of the DTO on the GitHub [repo](https://github.com/bhaidar/movie-tracker/tree/develop) of this article. 

In addition, we need to create a mapper helper function, that accepts as input, a Movie entity and returns a MovieDto object. Create a new mapper file under the path `apps\api\src\app\movietracker\mapper.ts` with the following content:

{% gist https://gist.github.com/bhaidar/6608530d4404a75dea4ce83ceb549644 %}

**Step 7**
Next, we need to setup the bootstrapping of the application. To prepare for that, let's create a new utils file under the path `apps\api\src\shared\utils.ts` and paste in the following:

{% gist https://gist.github.com/bhaidar/f6caa685de72341c994c15a3851779fa %}

This async function returns an object containing the connection string that is ready from the `ormconfig.json` file with a connection string name of `default`. This will be the default connection string used by TypeORM.

**Step 9**
Replace the content of the `app.module.ts` with the following:

{% gist https://gist.github.com/bhaidar/547c78cf41e5e25acf916c981037e913 %}

I converted the `AppModule` into a `DynamicModule` to accept a connection string. This connection string is then used to initialize and configure the `TypeOrmModule` module at the root level.

> You can read more about dynamic modules at the Nest.js [official document website](https://docs.nestjs.com/modules#dynamic-modules).

**Step 10**
The final configuration step involves bootstrapping the application inside the `main.ts` file located at `apps\api\src\`.

Paste the following code into the `main.ts` file:

{% gist https://gist.github.com/bhaidar/3e6b18800bc575e2c7548d6eeaad04d4 %}

The `bootstrap()` method starts by creating a new Nest.js app by using the `NestFactory.create()` method. This method accepts the root module, in this case it is the `AppModule`. 

Notice how we are calling the `AppModule.forRoot(await getdbConnectionOptions(process.env.NODE_ENV))` method and passing to it a dynamic connection string? This helps running the application on multiple environments without having to change any single line of code.

Then it adds the `ValidationPipe` as a global pipe to the application. This way, the input validation is applied to each and every action on all controllers in the app.

Finally, it starts listening on a port defined by means of an environment variable and defaults to `3000`.

Let's add some NPM scripts to run the backend API:

```json
"watch:server": "nodemon",`
"build:server": "tsc -p ./apps/api/tsconfig.app.json",
"run:server": "node -r dotenv/config -r source-map-support/register dist/api/src/main.js",
```

The `watch` script uses `nodemon` to run the application. This way, any changes made to the backend API files will cause the node server to restart automatically without having to stop and start the app again.

The contents of the `nodemon.json` configuration file located at the root of the workspace is as follows:

{% gist https://gist.github.com/bhaidar/5d907f03c8fd133fbee0a21067924c6f %}

It watches all files inside the `apps\api\src` folder and executes the following commands every time the server restarts:
`"exec": "yarn build:server && yarn run:server",`

Basically, the `build:server` builds the Nest.js app by running the Typescript compiler against the Nest.js app folder. The `run:server` simply runs the Nest.js app from the compiled version of the application and includes the `dotenv/config` module. This module imports any environment variables defined inside the `.env` file located at the root of the workspace.

For instance, you can define the PORT and any other relevant data inside this file.

Let's run the Docker container first and then the Web API by using the following commands in a terminal window:

```bash
yarn run run:services
yarn run watch:server
```

You should see a statement on your terminal window saying something like `[Bootstrap] Server started running on http://localhost:3000`.

To save time, I won't be testing the Web API via Postman. Instead, I will cover the front-end part of this application and test the Web API via the app itself.

##Building the Angular client-side App 
In the section **Create the Movie Tracker Nx Workspace** we've added three main libraries under `movietracker` folder:

- movietracker\ui
- movietracker\core
- movietracker\movies

Now we will fill the gaps by creating the necessary components needed to build our Movie Tracker CRUD page.

**Step 1**
Install the Angular Material module into the project by running this command:
`ng add @angular/material`

It installs the Angular Material module and all the related modules.

Next, create a new Typescript code file `ui-material.ts` inside the `libs\movietracker\ui\src\lib\` and paste in the following:

{% gist https://gist.github.com/bhaidar/a1a24002dae89db1e700a3b09a264471 %}

I've bundled all the required Angular Material modules inside a `material` array.

Next, we need to include this array in the `imports` and `exports` arrays at the `movietracker-ui.module` level. This way, any other module importing `movietracker-ui.module` will be able to use the Angular Material modules.

```typescript
@NgModule({
  imports: [CommonModule, RouterModule, ...material],
  declarations: [],
  exports: [...material]
})
export class MovieTrackerUiModule {}
```

**Step 2**
In the `movietracker\ui` module, add a new component `app-layout.component` to render the general layout of the app.

Run the command to create the component:
`ng g component components/app-layout --project=movietracker-ui`

This command creates a new component under the path `libs\movietracker\ui\src\lib\components\app-layout`.

Paste the following code in the `app-layout.component.html` file:

{% gist https://gist.github.com/bhaidar/bbee202847a1ee2a4db745fd9a984421 %}

This renders an Angular Material toolbar at the top of the component together with a `router-outlet` to allow other components to render beneath this toolbar.

Make sure to include this CSS class inside the `app-layout.component.scss` file as follows:

```css
.fill-remaining-space {
  display: flex;
  justify-content: space-between;
}
```

We will also add a `star-rating` component to use on the Edit and Create Movie forms. You can check components at the GitHub repo of this article.

Now let's import and export this component to the `movietracker-ui.module` so that it is available to other modules in the application:

```typescript
@NgModule({
  imports: [CommonModule, RouterModule, ...material],
  declarations: [AppLayoutComponent, StarRatingComponent],
  exports: [AppLayoutComponent, ...material, StarRatingComponent]
})
export class MovieTrackerUiModule {}
```

That's it for the `movietracker-ui.module`. Let continue with the rest of libs and modules.

**Step 4**
Create a new Typescript Interface `actions.interface.ts` inside the `movietracker\core` module with the following content:

```typescript
export interface MtAction {
  type: any;
  payload?: any;
  label?: string;
}
```

This interface is used to wrap event payloads later on.

The `movietracker-core.module` imports and exports common Angular modules needed in the application in addition to importing and exporting the `movietracker-ui.module`. Inside the `movietracker` Angular app we just import this core module having all needed dependencies. 

{% gist https://gist.github.com/bhaidar/fe64d2c3508d4e9a4909e75a3844b98f %}

**Step 5**
Create the Movie Typescript interface inside the `libs\interfaces\src\lib\movie.interface.ts` with the following content:

```typescript
export interface Movie {
  id?: string;
  title: string;
  watchedOn: Date;
  genre?: string;
  rating?: number;
}
```

**Step 6**
Let's create the `movietracker.service.ts` service inside the `libs\api-services` library.

Run the following command:
`ng g service movietracker --project=api-services`

The command creates the service. Now, let's paste in the following inside this service:

{% gist https://gist.github.com/bhaidar/863c1258d6dba419b56b542788dff522 %}

The source code is self-explanatory. In brief, this service implements the **searchMovies()**, **addMovie()**, **deleteMovie()** and **updateMovie()** methods.

It makes use of the **HttpClient** object to send HTTP Requests to the backend to communicate with the backend Web API.

**Step 7**
Let's create the `movietracker-movie-list` component inside the `movietracker\movies` library.

The next command being:
`ng g component containers/movietracker-movies-list --project=movietracker-movies`

The command above creates the component in the `movietracker-movies` module. This is a smart component or what we call a container component. That's why I place it inside the `containers` folder to distinguish it from the other dump or presentational components we will build shortly.

> Learn more about smart and presentational components in Angular with this [reference](https://blog.angular-university.io/angular-2-smart-components-vs-presentation-components-whats-the-difference-when-to-use-each-and-why/).

Paste in the following HTML markup inside the `movietracker-movies-list.component.html` file:

{% gist https://gist.github.com/bhaidar/35f10209eaff432f2853df614397ea59 %}

The component uses three presentational components:
- `movietracker-search-bar`: This component displays a search box to allow the user to filter for movies.
- `movietracker-grid`: This component displays the movies in a tabular form. For each and every row, you have two buttons to edit or delete a movie.
`- move-dialog-box`: This component is used as a Dialog component to edit, create and delete a movie.

You can generate the components by running the following commands:

```bash
ng g component components/movietracker-grid --project=movietracker-movies
ng g component components/movietracker-search-bar --project=movietracker-movies
ng g component components/movie-dialog-box --project=movietracker-movies
```

You may check the GitHub [repo](https://github.com/bhaidar/movie-tracker/tree/develop) of this article to go through the components.

Let's add a new NPM script to the `package.json` file to run the `movietracker` app:
`"watch:movietracker": "ng serve movietracker",`

Now we will run the application and check the UI:

```bash
yarn run run:services
yarn run watch:server
yarn run watch:movietracker
```

![App features](https://thepracticaldev.s3.amazonaws.com/i/g3z6szm4o0gvuxgv20tj.png)

The user can:
- View all movies
- Filter movies
- Add a new movie
- Edit an existing movie
- Delete an existing movie

For instance, when the user clicks on the `Edit` button on a movie row, the following code executes:

{% gist https://gist.github.com/bhaidar/6b8767ce92779820d7aa8344f073e25b %}

The code creates and opens a new Angular Material Dialog. It then listens to the closed event to receive the updated movie and then it calls the server to update the movie in the database.

In addition, the component injects the `MovieTrackerService` that it uses to communicate with the backend Web API.

The create and delete functions are similar to the above. You can check the entire code-behind the `movietracker-movies-list.component` here:

{% gist https://gist.github.com/bhaidar/93711e9588f8a4f930779d8527063439 %}

You can always check the detailed explanation of the components by reading the first article of this series [Angular and the REST](https://dev.to/thisdotmedia/angular-and-the-rest-4ho7).

**Step 8**
Finally, let's run the application and try its functionality.

```bash
yarn run run:services
yarn run watch:server
yarn run watch:movietracker
```

To filter the movies:
![Filter movies](https://thepracticaldev.s3.amazonaws.com/i/nee11s3rvhqyq24dzqc7.png)

To add a new Movie:
![Add a movie](https://thepracticaldev.s3.amazonaws.com/i/nee11s3rvhqyq24dzqc7.png)

To edit an existing movie:
![Edit a movie](https://thepracticaldev.s3.amazonaws.com/i/nee11s3rvhqyq24dzqc7.png)

To delete a movie:
![Delete a movie](https://thepracticaldev.s3.amazonaws.com/i/nee11s3rvhqyq24dzqc7.png)

##Conclusion
We've seen how easy it is to connect an Angular app with a Nest.js application. 

In the next article, I will add support for authentication using JSON Web Token (JWT).

This post was written by [Bilal Haidar](https://www.bhaidar.dev/), a mentor with [This Dot](https://thisdot.co/).

*You can follow him on Twitter at @bhaidar.*

*Need JavaScript consulting, mentoring, or training help? Check out our list of services at [This Dot Labs](https://thisdot.co).*