A reusable NestJS module for Prisma ORM with base classes for controllers, services, and DTOs.
npm install nestjs-prisma-base
- Ready-to-use Prisma module with proper lifecycle management
- Base service with common CRUD operations
- Base controller with configurable REST endpoints
- Base DTOs for standardizing request/response data
- Utility decorators for easier implementation
- Factory functions to auto-generate components from Prisma models
- Selective endpoint activation for precise API control
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma-base';
@Module({
imports: [
PrismaModule.forRoot(),
// Your other modules
],
})
export class AppModule {}
// user.dto.ts
import { BaseCreateDto, BaseUpdateDto, BaseResponseDto } from 'nestjs-prisma-base';
import { IsEmail, IsString, IsOptional } from 'class-validator';
export class CreateUserDto extends BaseCreateDto {
@IsString()
name: string;
@IsEmail()
email: string;
@IsString()
password: string;
}
export class UpdateUserDto extends BaseUpdateDto {
@IsString()
@IsOptional()
name?: string;
@IsEmail()
@IsOptional()
email?: string;
}
export class UserResponseDto extends BaseResponseDto {
name: string;
email: string;
}
// user.service.ts
import { Injectable } from '@nestjs/common';
import { BaseService, ModelName, PrismaService } from 'nestjs-prisma-base';
import { User } from '@prisma/client';
import { CreateUserDto, UpdateUserDto } from './user.dto';
@Injectable()
@ModelName('user')
export class UserService extends BaseService<User, CreateUserDto, UpdateUserDto> {
constructor(prisma: PrismaService) {
super(prisma);
}
// Add custom methods here
}
// user.controller.ts
import { Controller } from '@nestjs/common';
import { BaseController, EnableEndpoint, EndpointType, EnableAllEndpoints, DisableEndpoint } from 'nestjs-prisma-base';
import { User } from '@prisma/client';
import { UserService } from './user.service';
import { CreateUserDto, UpdateUserDto } from './user.dto';
@Controller('users')
// Option 1: Enable specific endpoints
@EnableEndpoint(EndpointType.FIND_ALL)
@EnableEndpoint(EndpointType.FIND_ONE)
@EnableEndpoint(EndpointType.CREATE)
// Option 2: Enable all endpoints at once
// @EnableAllEndpoints()
// Option 3: Enable all except specific ones
// @EnableAllEndpoints()
// @DisableEndpoint(EndpointType.REMOVE)
export class UserController extends BaseController<User, CreateUserDto, UpdateUserDto> {
constructor(private readonly userService: UserService) {
super(userService);
}
// Add custom endpoints here
// Don't forget to enable your custom endpoints!
@EnableEndpoint('findByEmail')
@Get('by-email/:email')
findByEmail(@Param('email') email: string) {
return this.userService.findByEmail(email);
}
}
// user.module.ts
import { createModelModule, EndpointType } from 'nestjs-prisma-base';
// Option 1: Create module with specific enabled endpoints
export const UserModule = createModelModule({
modelName: 'user',
routePath: 'users',
enabledEndpoints: [EndpointType.FIND_ALL, EndpointType.FIND_ONE, EndpointType.CREATE],
});
// Option 2: Create module with all endpoints enabled
export const ProductModule = createModelModule({
modelName: 'product',
enableAllEndpoints: true,
});
// Option 3: Create module with custom service
export const CategoryModule = createModelModule({
modelName: 'category',
enableAllEndpoints: true,
serviceType: CategoryService, // Your custom service class
providers: [
/* Additional providers */
],
imports: [
/* Additional imports */
],
exports: [
/* Additional exports */
],
});
// app.module.ts
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma-base';
import { UserModule } from './user.module';
@Module({
imports: [
PrismaModule.forRoot(),
UserModule,
// Other modules
],
})
export class AppModule {}
Important: By default, all endpoints are disabled for security reasons. In version 0.2.0 and above, you must explicitly enable each endpoint you want to expose. This provides better security and control over your API surface.
export enum EndpointType {
FIND_ALL = 'findAll', // GET /resource
FIND_ONE = 'findOne', // GET /resource/:id
CREATE = 'create', // POST /resource
UPDATE = 'update', // PATCH /resource/:id
REMOVE = 'remove', // DELETE /resource/:id
}
When using this package with Swagger documentation, endpoints that are disabled will be automatically hidden from the Swagger UI. This is accomplished through the ApiExcludeDisabledEndpoint
decorator that's applied to all standard endpoints in the BaseController
.
If you're creating custom endpoints, you can use the decorator to hide them from Swagger when they're disabled:
@Get('custom-endpoint')
@ApiExcludeDisabledEndpoint('customEndpoint')
customEndpoint() {
if (!this.isEndpointEnabled('customEndpoint')) {
throw new NotFoundException('Endpoint not available');
}
// Your implementation
}
This requires the @nestjs/swagger
package to be installed in your project.
You can enable endpoints at the controller level:
@Controller('users')
@EnableEndpoint(EndpointType.FIND_ALL)
@EnableEndpoint(EndpointType.FIND_ONE)
export class UserController extends BaseController<User, CreateUserDto, UpdateUserDto> {
// ...
}
Or enable all endpoints at once:
@Controller('users')
@EnableAllEndpoints()
export class UserController extends BaseController<User, CreateUserDto, UpdateUserDto> {
// ...
}
You can disable specific endpoints even when using @EnableAllEndpoints()
:
@Controller('users')
@EnableAllEndpoints()
@DisableEndpoint(EndpointType.REMOVE)
export class UserController extends BaseController<User, CreateUserDto, UpdateUserDto> {
// ...
}
You can also selectively enable endpoints at the method level:
@Controller('users')
export class UserController extends BaseController<User, CreateUserDto, UpdateUserDto> {
// Only this method will be available
@EnableEndpoint('findAdmins')
@Get('admins')
findAdmins() {
return this.userService.findAdmins();
}
}
MIT