-
Notifications
You must be signed in to change notification settings - Fork 1
Controller abstract
Extending your controllers with the CrudController
will give you access to a set of basic Restful endpoints.
Method | URL | Response | |
---|---|---|---|
Create model | POST | / | Model |
Get model by id | GET | /:id | Model |
Get many by id | GET | /many/:ids | Model[] |
Get all | GET | / | Model[] |
Overwrite model | PUT | /:id? | Model |
Merge model | PATCH | /:id? | Model |
Delete model | DELETE | /:id | Model |
Implementing the CrudController
is pretty straightforward. The only prerequisite is that you have created a CrudService
class which executes all of the actions the controller has to perform. Afterwards you can just extend your controller class as shown below.
@Controller('users')
export class UserController extends CrudController<IUserModel> {
constructor(private readonly service: UserService) {
super(service);
}
}
In almost every scenario you don't want all endpoints to be publicly available. This is why the package supports the use of NestJS guards on the generated endpoints.
const permissions = {
admin: {
guards: [RolesGuard],
data: { roles: [Role.ADMIN] },
},
user: {
guards: [RolesGuard],
data: { roles: [] },
},
};
@Controller('users')
export class UserController extends CrudController<IUserModel> {
constructor(private readonly service: UserService) {
super(service, {
create: permissions.admin,
read: permissions.user,
update: permissions.admin,
delete: permissions.admin,
});
}
}
Guards can be defined per CRUD action as a second parameter of the super()
call and accept guards as defined in the NestJS documentation. The only difference is that provided data has to be retrieved from the context.metadata
attribute instead of the reflector. You can support both methods as show below.
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: any) {
const roles: Role[] =
context.metadata?.roles ||
this.reflector.get<string[]>('roles', context.getHandler());
...
}
}
In order to allow query parameter functionality in custom endpoints you will have to mold the received parameters into the correct format and forward it to the service. This can be easily achieved using the queryToOptions()
method as shown below.
@Controller('users')
export class UserController extends CrudController<IUserModel> {
constructor(private readonly service: UserService) {
super(service);
}
@Get('inactive')
getInactive(@Req() request: INuRequest, @Query() query: IHttpOptions) {
const options: INuOptions = this.queryToOptions(query);
options.request = request;
this.service.getInactive(options);
}
}
Made by Martin Drost - Buy me a ☕