Eggy Dev DocsEggy Dev Docs

Implement CRUD Service

Build the service layer that talks to MongoDB.

Overview

Now that we have a schema and DTOs, we can build the service (business logic) that talks to MongoDB. CRUD stands for Create, Read, Update, Delete—the basic actions for working with data.

1. Create the service

Create src/tasks/tasks.service.ts:

src/tasks/tasks.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Task, TaskDocument } from './task.schema';
import { CreateTaskDto } from './dto/create-task.dto';
import { UpdateTaskDto } from './dto/update-task.dto';

@Injectable()
export class TasksService {
  constructor(
    @InjectModel(Task.name)
    private readonly taskModel: Model<TaskDocument>,
  ) {}

  async findAll() {
    return this.taskModel.find().sort({ updatedAt: -1 }).lean();
  }

  async findOne(id: string) {
    const task = await this.taskModel.findById(id).lean();
    if (!task) throw new NotFoundException(`Task ${id} not found`);
    return task;
  }

  async create(input: CreateTaskDto) {
    const task = await this.taskModel.create(input);
    return task.toObject();
  }

  async update(id: string, input: UpdateTaskDto) {
    const task = await this.taskModel
      .findByIdAndUpdate(id, input, { new: true, runValidators: true })
      .lean();
    if (!task) throw new NotFoundException(`Task ${id} not found`);
    return task;
  }

  async remove(id: string) {
    const result = await this.taskModel.findByIdAndDelete(id).lean();
    if (!result) throw new NotFoundException(`Task ${id} not found`);
  }
}

Key ideas:

  • @InjectModel injects the Mongo collection.
  • lean() returns plain objects (lighter than full Mongoose documents).
  • NotFoundException automatically maps to a 404 HTTP status.

2. Register the service in a module

In tasks.module.ts, export the service in case other modules need it later:

src/tasks/tasks.module.ts
...
import { TasksService } from './tasks.service'; 

@Module({
  imports: [MongooseModule.forFeature([{ name: Task.name, schema: TaskSchema }])],
  controllers: [],
  providers: [] 
  providers: [TasksService], 
  exports: [] 
  exports: [TasksService], 
})
export class TasksModule {}

Restart or continue running npm run start:dev. If the app compiles, your service is ready for use.

Commit your service work

Run git status to confirm which files changed (for example, tasks.service.ts and updates to tasks.module.ts). Stage them and commit on your feature/crud-implementation branch:

git add src/tasks/tasks.service.ts src/tasks/tasks.module.ts
git commit -m "feat: add task service"

Smaller commits make PR reviews faster and easier to follow.

Next, head to Controllers & Routes to expose these operations over HTTP.