
Создание CRUD RESTfull API может занять некоторое время, особенно у новичков, или может быть очень скучным для некоторых опытных разработчиков. Но сегодня я собираюсь показать, как это можно сделать быстро и по-другому, с помощью NestJS и @nestjsx/crud.
Требования
npm i -g @nestjs/cli npm i --save @nestjs/typeorm typeorm pg npm i --save @nestjs/swagger swagger-ui-express npm i class-validator --save npm i @nestjsx/crud class-transformer class-validator npm i @nestjsx/crud-typeorm @nestjs/typeorm typeorm
Первые шаги
Сначала нам нужно создать новый проект NestJS.
nest new project-name
Затем мы можем подключиться к базе данных PostgreSQL и pgAdmin 4 с помощью docker-compose. Просто скопируйте файл docker-compose.yml в корневой каталог проекта и запустите docker-compose.
// docker-compose.yml
version: '3'
services:
postgres_compose:
image: postgres
environment:
POSTGRES_PASSWORD: '1StrongPassword'
POSTGRES_USER: 'postgres'
POSTGRES_DB: 'myDatabase'
ports:
- '15432:5432'
volumes:
- /var/docker/postgres/db:/var/lib/postgresql/data
networks:
- postgres-compose-network
pgadmin_compose:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: '[email protected]'
PGADMIN_DEFAULT_PASSWORD: '1StrongPassword'
ports:
- '16543:80'
depends_on:
- postgres_compose
networks:
- postgres-compose-network
networks:
postgres-compose-network:
driver: bridge
Затем нам нужно открыть страницу pgAdmin: http://localhost:16543/ и создать подключение к серверу с Host: postgres_compose. Теперь мы можем создать базу данных.

Далее нам нужно подключить NestJS к серверу базы данных. Итак, прежде всего, создайте файл ormconfig.json в корневом каталоге проекта с необходимыми конфигурациями для подключения к базе данных docker. Затем нам нужно только вызвать forRoot() без каких-либо опций в модуле приложения.
// ormconfig.json
{
"type": "postgres",
"host": "localhost",
"port": 15432,
"username": "postgres",
"password": "1StrongPassword",
"database": "myDatabase",
"entities": ["dist/**/*.entity{.ts,.js}"],
"synchronize": true,
"logging": true
}
// app.module.ts
@Module({
imports: [TypeOrmModule.forRoot(), UsersModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Теперь мы можем установить и настроить Swagger API. Нам нужно создать DocumentBuilder в нашем файле main.ts.
// main.ts
const options = new DocumentBuilder()
.setTitle('My RESTful CRUD API')
.setDescription('example')
.setVersion('version')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('/api', app, document);
CRUD
Теперь наступает лучшая часть!
Обычно я использую следующую структуру каталогов.
src/
├── users/
├── user/
│ ├── controllers/
│ │ ├── dto/
│ │ │ └── create.dto.ts
│ │ └── user.controller.ts
│ ├── entities/
│ │ ├── user-typeorm/
│ │ │ └── user-typeorm.entity.ts
│ │ └── user.interface.ts
│ ├── services/
│ │ └── user.service.ts
└── user.module.ts
Для этого примера мы собираемся создать простой CRUD API для регистрации пользователей.
Во-первых, объект, простой объект пользователя, который реализует пользовательский интерфейс с именем, адресом электронной почты и возрастом.
// user.entity.ts @Entity('user') export class UserEntity implements User { @PrimaryGeneratedColumn() id: number; @IsNotEmpty() @Column() name: string; @IsNotEmpty() @Column() email: string; @IsNotEmpty() @Column() age: number; }
Затем нам нужно создать UserService, который мы можем использовать в контроллерах. С @nestjsx/crud наш сервис состоит всего из нескольких строк и делает все, что нужно.
// user.service.ts @Injectable() export class UserService extends TypeOrmCrudService<UserEntity> { constructor(@InjectRepository(UserEntity) repo: Repository<UserEntity>) { super(repo); } }
Контроллеру также нужно несколько строк кода, чтобы идентифицировать сущность, DTO и внедрить UserService. Сделанный!
// user.controller.ts @ApiTags('User') @Crud({ model: { type: UserEntity, }, routes: { exclude: ['createManyBase', 'replaceOneBase'], deleteOneBase: { returnDeleted: true, }, }, dto: { create: CreateUser, update: CreateUser, }, }) @Controller('user') export class UserController implements CrudController<User> { constructor(public service: UserService) {} }
DTO не требуются, но рекомендуется всегда использовать DTO, особенно в теле запросов REST.
// create-user.dto.ts
export class CreateUser {
@ApiProperty()
@IsNotEmpty()
public name: string;
@ApiProperty()
@IsNotEmpty()
public email: string;
@ApiProperty()
@IsNotEmpty()
public age: number;
}
И, наконец, мы создаем UsersModule и можем запускать API нашего сервера.
// users.module.ts @Module({ imports: [TypeOrmModule.forFeature([UserEntity])], providers: [UserService], controllers: [UserController], }) export class UsersModule {}


Вывод
Как видите, через пару минут у нас есть полный REST API, который работает очень хорошо. Следующим шагом может быть создание некоторых валидаторов, пользовательских запросов, перехватчиков и так далее.
Git: https://gitlab.com/DylanMatiasMarques/medium-nestjs-crud
Для получения дополнительной информации обратитесь к документации:
https://github.com/nestjsx/crud
https://docs.nestjs.com/