Basic CRUD operations with NestJs, TypeScript, Fastify & MongoDB
Fastify is a web framework for building efficient and high-performance web applications and APIs in Node.js. It is designed to be lightweight and focused on speed, making it particularly suitable for applications that require low latency and high throughput. Fastify was developed to address some of the shortcomings of existing Node.js frameworks in terms of performance and simplicity.
Let’s go
Create your NestJs project
npx nest new project-name
Our project name is : fastify-mongo-crud and we’ll use yarn but you can choose any other package manager listed.
Add the Fastify package with this command
yarn add @nestjs/platform-fastify
By default , when you create a new Nestjs project, Nest install “@nestjs/platform-express” package (see the image below),
Because we’ll use Fastify we dont need this express platform anymore.
Create a nest resource with
npx nest generate resource articles --no-spec
then select REST API
Nest will ask you i f you want to generate CRUD entry points : Type ‘n’ to say no.
Great! now as we already know, the default framework is Express, we need to change it to Fastify.
In the root of the project, pass the code bellow into main.ts file
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter,NestFastifyApplication} from '@nestjs/platform-fastify';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.listen(3000);
}
bootstrap();
PS: If you have the following issue :
Type 'NestFastifyApplication<RawServerDefault>' does not satisfy the constraint 'INestApplication'.
Perhaps there is a compatibility versions issue of both @nestjs/platform-fastify
and NestJS core packages, so run
yarn upgrade-interactive --latest
to update the dependencies to their last stable versions.
Once you’ve done with that, install mongoDb to the project
yarn add @nestjs/mongoose mongoose
Once the mongoose package is installed, we need to import the MongooseModule into the root AppModule. At this stage, your app.module.ts should be like :
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticlesModule } from './articles/articles.module';
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [ MongooseModule.forRoot('mongodb://mongO_uri'), ArticlesModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Do not forget to replace the `mongodb://mongO_uri`
by a real mongoDb uri.
Create our article schema in `src/article/schema/article.schema.ts`
:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
export type ArticleDocument = HydratedDocument<Article>;
@Schema()
export class Article {
@Prop()
title: string;
@Prop()
slug: string;
@Prop()
content: string;
}
export const ArticleSchema = SchemaFactory.createForClass(Article);
Import the MongooseModule, Article and ArticleSchema in your article.module.ts file
import { Module } from '@nestjs/common';
import { ArticlesService } from './articles.service';
import { ArticlesController } from './articles.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { Article, ArticleSchema } from './schema/article.schema';
@Module({
imports:[MongooseModule.forFeature([{ name: Article.name, schema: ArticleSchema }])],
controllers: [ArticlesController],
providers: [ArticlesService]
})
export class ArticlesModule {}
It’s time to run the project to see if everything works properly.
Run it with `yarn start dev`
If not and if you got this error:
const stringWidth = require('string-width');
Error [ERR_REQUIRE_ESM]: require() of ES Module
Just delete the node-module file and install all the dependencies again.
Great! MongoDb and Fastify added and set up successfully
Let’s create our services now in order to post and get data from the database.
`src/articles/articles.service.ts`
import { Injectable } from '@nestjs/common';
import { Article } from './schema/article.schema';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
@Injectable()
export class ArticlesService {
constructor(@InjectModel(Article.name) private readonly articleModel: Model<Article>){}
async postArticle( body: Article):Promise<Article> {
const create = new this.articleModel(body)
return create.save()
}
async getArticles(){
return this.articleModel.find().exec()
}
}
`postArticle()`
is here for creating new article and save it to the mongoDb database and `getArticles()`
for getting all the articles from the database
Once we created all the services we want, let’s create the controller:
`src/articles/articles.controller.ts`
import { Body, Controller, Get, Post } from '@nestjs/common';
import { ArticlesService } from './articles.service';
import { Article } from './schema/article.schema';
@Controller('articles')
export class ArticlesController {
constructor(private readonly articlesService: ArticlesService) {}
@Post('create')
postArticle( @Body() body : Article ){
return this.articlesService.postArticle(body);
}
@Get('get-articles')
getArticles(){
return this.articlesService.getArticles();
}
}
For each function, we defined the request type (POST or GET only for this example), the pathname and the necessary parameters.
Great! now let’s open postman to see if we can post and get with our simple Fastify api implementation.
`localhost:3000/articles/get-articles`
result :
`localhost:3000/articles/create`
result :
Congratulation, we’ve delved into the world of basic CRUD operations, leveraging the power of NestJs, TypeScript, Fastify, and MongoDB. By mastering these fundamental techniques, you’ve laid a strong foundation for creating robust applications. As you continue to explore and refine your skills, remember that the journey of a developer is an ongoing evolution.
For more about Fastify 👉🏾 : https://fastify.dev/
You can find the whole project on Github 👇🏾 : https://github.com/laetitiaouelle/fastify-mongo-crud
Follow me there :
linkedin.com/in/laetitia-christelle-ouelle-89373121b/
twitter.com/OuelleLaetitia
Happy coding ! 😏