Using in-memory-db With NestJS

In this piece, we will see how we can use in-memory-db to perform CRUD operations

Santosh Yadav
Jan 13 · 4 min read
NestJS logo

Let’s see why we should and how we can use in-memory-db, you can access the source code on GitHub.


Why

Below are two scenarios where you may need in-memory-db.

  • POC (Proof of Concept): When you need to create a quick POC for an upcoming project and you want to create an API with NestJS, for integration with a UI.
  • Mock: You need to write the test cases and you want to mock the DB operations. This is the perfect use case for using in-memory-db.

How

Follow the below steps to create an API with in-memory-db.

  • Run the below command to create a NestJS project.
nest new in-memory-demo
  • Once the app is ready, run the below command to install in-memory-db support.
nest add @nestjs-addons/in-memory-db
  • We will create a ProductController with CRUD operations, so we will add a module and controller for the same.
nest generate module product
nest generate controller product
  • Next, we need an entity. Create a new folder entities inside the product folder.
  • Create a new file product.entity.ts and add the below code.
product.entity.ts
  • In the above code, InMemoryDBEntity adds an id property to any interface that extends this interface.
  • Next, we need to add some code to the controller and the module. There are two ways in which you can perform CRUD operations, by providing your own implementation or using the built-in InMemoryDBEntityAsyncController or InMemoryDBEntityController.

We will see both approaches, let’s see how to implement our own.

  • Open app.controller.ts and add the below code, this file already exists.
app.controller.ts

You can see in the above code that we have added the below code to provide the Post method.

@Post()
AddProduct(@Body() product: ProductEntity): ProductEntity {
return this.productService.create(product);
}
  • The ProductService is instantiated from InMemoryDBService. It comes with many built-in methods to perform CRUD operations, without writing a single line of code. The service contains two types of methods, sync and async which return an observable.
  • In the above code, the below-highlighted code is needed to create an instance of service which takes the entity ProductEntity and provides all methods.
constructor(private readonly appService: AppService,                           private productService: InMemoryDBService<ProductEntity>) {}

The methods that we are going to implement are:

  • getAll(): Retrieve all records.
  • create(): Insert new records. Use createMany to insert multiple records.
  • update(): Update the record for the provided id in the request body.
  • delete(): Delete the record for the provided id.
  • query(): Query the data from the records added.

Below is the complete code:

app.module.ts

Now, in most cases, you just want to provide CRUD operations and if we keep adding the same code, it will cause code duplication and the package keeps that in mind.

It has InMemoryDBEntityAsyncController orInMemoryDBEntityController to achieve the same.

  • To implement CRUD operations using the above interface, you can just add the below lines of code.
product.controller.ts

The InMemoryDBEntityAsyncController provides the implementation for the below methods by default.

  • create
  • update
  • updateMany
  • delete
  • deleteMany
  • get
  • getMany

For Feature Modules

In case you have a different feature module, you need to use the forFeature method to register InMemoryDBModule. The below code gives an example of how to use it for ProductModule.

product.module.ts

You can also use the feature-specific instances of InMemoryDBService. You need to use the below code in the constructor.

constructor(@InjectInMemoryDBService('product') private productService: InMemoryDBService<ProductEntity>)

Seeding Test Data

For testing, you may need to create some dummy data and we don’t expect you to create all records manually, this is where you can use seed method to create dummy data.

  • Create a new Module, Controller, and Entity by using the below command.
nest generate module employee
nest generate controller employee
  • Next, add a new entities folder in the employee folder and add a new file employee.ts and add the below code.
employee.ts
  • Next, register the InMemoryDBModule for employee Module, add the below code in employee.module.ts
employee.module.ts
  • Final Step is to use seed method to create 10 dummy records.
employee.controller.ts

Next, trigger the seed method by accessing the http://localhost:3000/employee/seed which will create 10 records.

You can update the count, in the below method to create more records.

this.employeeService.seed(recordFactory, 10);

You can use postman to test out the APIs. In the next article, we will see how we can add swagger capabilities to create a test page for testing.

You can refer to the code for this demo at:

Conclusion

in-memory-db is widely used in other frameworks like .Net, Java, and Angular to create POCs or create a mock back end.

This package brings the same capability to the NestJS ecosystem and you can easily plugin the same with existing NestJS projects to create POCs.

Thanks to Wes Grimes and the team for creating this package.

Better Programming

Advice for programmers.

Santosh Yadav

Written by

Santosh is GDE for Angular and Web Technologies, he is open source contributor for Angular, NgRx and Writer at AngularInDepth and DotNetTricks.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade