generate-crud v1.2.3
Generate crud Nestjs
This package provides a CRUD service for database MySQL build with TypeORM
Installation
npm i generate-crud
1. REST API with swagger
Usage
Assume you have some TypeORM enitity:
@Entity()
export class ProductEntity{
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
price: number;
}
Note: id is required
Then you need to create a service:
import { CrudTypeormService } from 'generate-crud';
@Injectable()
export class ProductService extends CrudTypeormService<ProductEntity> {
constructor(
@InjectRepository(ProductEntity)
private productRepository: Repository<ProductEntity>,
) {
super(productRepository);
}
}
DTO is used for creating or updating entity, we will need it in controller
import { CrudTypeormController } from 'generate-crud';
@Controller('product')
export class ProductController extends CrudTypeormController(ProductEntity, InputProductDto) {
constructor(private readonly productService: ProductService) {
super(productService);
}
}
After that you need to provide your service in a controller:
import { CrudTypeormController } from 'generate-crud';
@Controller('product')
export class ProductController extends CrudTypeormController(ProductEntity, InputProductDto) {
constructor(private readonly productService: ProductService) {
super(productService);
}
}
Finally in main.js
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Test api')
.setVersion('1.0')
.addTag('testapi')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
2. Authentication with swagger and JWT
First you have some entity with other information: (username and password are included in Auth)
import { Auth } from 'generate-crud';
import { Entity, Column } from 'typeorm';
@Entity()
export class UserEntity extends Auth {
@Column()
firstName: string;
@Column()
lastName: string;
}
Then you need to create a auth Service:
import { AuthService } from 'generate-crud';
@Injectable()
export class UserService extends AuthService<UserEntity> {
constructor(
@InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>,
) {
super(userRepository);
}
}
InputUserDto for creating an account for user, there is no need to add username and password, only other information like firstName, lastName ...
import { Credential } from 'generate-crud';
import { ApiProperty } from '@nestjs/swagger';
export class InputUserDto extends Credential {
@ApiProperty()
firstName: string;
@ApiProperty()
lastName: string;
}
And create UserController extends from AuthController
import { Controller } from '@nestjs/common';
import { UserService } from './user.service';
import { AuthController } from 'generate-crud';
import { UserEntity } from './user.entity';
import { InputUserDto } from './create-user.dto';
@Controller('user')
export class UserController extends AuthController(UserEntity, InputUserDto) {
constructor(private readonly userService: UserService) {
super(userService);
}
}
Add JwtStrategy in providers of app.module.ts file
import { JwtStrategy } from 'generate-crud';
@Module({
...
providers: [JwtStrategy],
...
})
And in main.ts, edit config
const config = new DocumentBuilder()
.setTitle('Test api')
.setVersion('1.0')
.addTag('testapi')
.addBearerAuth(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
},
'JWT-auth',
)
.build();
3. Authorization with swagger and JWT
First, let's create a Role enum representing roles in the system:
export enum Role {
User = 'user',
Admin = 'admin',
}
Your User class must look as follows:
@Entity()
export class UserEntity extends Auth {
@Column()
firstName: string;
@Column()
lastName: string;
@Column({ type: 'enum', enum: Role, default: Role.User })
roles: Role;
}
And now we set authorization for users, for examples:
export const Permisson = {
create: [Role.User], // only 'user' role can create Product
findAll: [Role.Admin, Role.User], // both 'admin' and 'user' role can findAll product
findOne: [Role.User], // only 'user' role can findOne a Product
delete: ['all'], // every user can delete Product
patch: [], // every user can update Product
}
And pass Permission as a parameter of Product Controller
@Controller('product')
export class ProductController extends CrudTypeormController(
ProductEntity,
InputProductDto,
Permisson
) {
constructor(private readonly productService: ProductService) {
super(productService);
}
}
4. Using GraphQL
Usage
Assume you have some GraphQL schema :
@ObjectType('Product')
export class Product {
@Field((type) => ID)
id: number;
@Field()
name: string;
@Field()
price: number;
}
(Note: id is required)
After that you need to provide your service in a resolver:
@Resolver((type) => Product)
export class ProductResolver extends CrudTypeormResolver(Product) {
constructor(private productService: ProductService) {
super(productService);
}
}
5. Authentication with GraphQL
Usage
Assume you have some GraphQL schema :
@ObjectType('User')
export class User {
@Field((type) => ID)
id: number;
@Field()
username: string;
@Field()
password: string;
@Field()
firstName: string;
@Field()
lastName: string;
}
(Note: id is required)
InputUserDto for creating an account for user
import { Field, InputType } from '@nestjs/graphql';
@InputType()
export class UserInputDto {
@Field()
username: string;
@Field()
password: string;
@Field()
firstName: string;
@Field()
lastName: string;
}
Then we need to create a service
import { AuthResolver, AuthTokenService } from 'generate-crud';
@Resolver((type) => User)
export class UserResolver extends AuthResolver(User) {
constructor(
private userService: UserService,
private tokenService: AuthTokenService,
) {
super(userService);
}
}
After that we need to init AuthModule in UserModule
import { UserResolver } from './user.resolver';
import { AuthModule } from 'generate-crud';
@Module({
imports: [TypeOrmModule.forFeature([UserEntity]),AuthModule],
providers: [UserService, UserResolver],
exports: [TypeOrmModule],
})
Finally in AppModule, add Auth and AuthToken to entity list
import { JwtStrategy, Auth, AuthToken } from 'generate-crud';
@Module({
imports: [
TypeOrmModule.forRoot({
...
entities: [
...,
Auth,
AuthToken,
],
}),
],
controllers: [],
providers: [JwtStrategy],
})
6. Authorization with GraphQL
Pass Permission as a parameter of Product Controller, and provide a AuthTokenService
import { AuthTokenService, CrudTypeormResolver } from 'generate-crud';
@Resolver((type) => Product)
export class ProductResolver extends CrudTypeormResolver(Product, Permisson) {
constructor(
private productService: ProductService,
private tokenService: AuthTokenService,
) {
super(productService);
}
}
Then remember to import AuthModule in ProductModule
import { AuthModule } from 'generate-crud';
@Module({
imports: [TypeOrmModule.forFeature([ProductEntity]), AuthModule],
controllers: [ProductController],
providers: [ProductService, ProductResolver],
})
export class ProductModule {}