At the moment to implement nestjsx/crud is very easy to create a CRUD, but what happens if I want to omit the "Delete" ?
User service
#Injectable()
export class UserService extends TypeOrmCrudService<UserService>{
constructor(#InjectRepository(User) repo) {
super(repo)
}
}
Usercontroller
#Crud({
model: {
type: User
}
})
#Controller('todo')
export class UserController implements CrudController<UserService> {
constructor(public service: UserService) {}
}
It's very simple, with that I have my CRUD operations in less than one minute, but if I have to omit a operation, in this case, delete, do I have to create one by one my method? or how I can do it?
You can exclude or include specific routes using the routes property of the #Crud decorator. exclude allows you to list routes that will not be provided, while only lets you declare which routes will be provided.
You could use the following to specifically exclude the Delete route:
#Crud({
model: {
type: User
},
routes: {
exclude: ['deleteOneBase'],
}
See the nestjsx/crud routes section of the wiki for additional routes properties.
The #Crud decorator gives you lots of control over your routes. In addition to routes, you'll find the params and query properties to be incredibly useful.
Related
I'm using Prisma 3.15 with NestJS and need to split queries to two different data-sources. One is read-only replica and another is master database.
I don't want to manage these manually on each prisma call!
How can I split them automatically?
I can define two separate clients in PrismaService like this:
#Injectable()
export class PrismaService implements OnModuleInit {
constructor(
private readClient: PrismaClient,
private writeClient: PrismaClient
) {
this.readClient = new PrismaClient({
datasources: {db: {url: process.env.PRISMA_READ_DB_URL}},
});
this.writeClient = new PrismaClient({
datasources: {db: {url: process.env.PRISMA_WRITE_DB_URL}},
});
}
But how can I split queries between them?
Can I override prisma modules like this?
get user() {
// Do something with the user!!!
return this.readClient.user;
}
Disclaimer: My aspiration has obvious and good alternatives, but from what little I know about Nestjs I would not be surprised if supported the following "pattern" somehow.
Given these 2 DTOs:
export class AddExistingMemberDto {
#IsInt()
memberId: number;
}
export class AddNonExistingMemberDto {
#IsString()
username: string;
#IsEmail()
email: string;
}
Can Nestjs check which DTP the request body fulfils, and switch between different controller methods?
I tried:
#Controller('group')
export class GroupController {
#Patch(':id/members/add')
addExistingMember(
#Body() addExistingMemberDto: AddExistingMemberDto,
) {
console.log('Existing', addExistingMemberDt);
}
#Patch(':id/members/add')
addNonExistingMember(
#Body() addNonExistingMemberDto: AddNonExistingMemberDto,
) {
console.log('Non-existing', addNonExistingMemberDto);
}
}
But this always invokes with the first method.
Rationale: Having one controller method that checks the DTO is a fine alternative, but it does require me to merge my two different DTO classes. So I was just curious.
I am trying to change type of query in Express.js Request namespace. I allready using a custom atrribute, but this approach seems not working if attribute is already declared in #types (works just for new attributes added to Request).
This is my type declaration:
declare namespace Express {
export interface Query { [key: string]: any; }
export interface Request {
attr1?: string, // this is working
query: any // this is not working, query is still type of Query
}
}
and this is my ts.config
"typeRoots" : [
"./src/types",
"node_modules/#types"
]
Is there some another approach, how to redefine type of query attribute? (or another attribute from Request interface)
It seems only solution is use an Omit
import { Request as OriginalRequest } from 'express'
declare namespace Express {
export interface Request extends Omit<OriginalRequest, 'query'> {
query: any
}
}
As per nestjs doc page I am using this code:
#Controller('books')
export class BooksController {
constructor(
private readonly bookService: BooksService,
) {}
#SerializeOptions({
excludePrefixes: ['_'],
})
#Get()
async getAll(): Promise<Book[]> {
return this.bookService.getAll();
}
}
trying to strip _id (and presumably __v too) properties from the documents which are coming from mongodb/mongoose. Is there any other step I need to take to make it work? I have also tried placing the #SerializeOptions decorator over the #Controller - to no avail.
(It's only an exercise, IRL I would probably map id
caveat: new to web programming. I have the following in a sails project:
// in models/User.js
// user has many videos
module.exports = {
attributes: {
videos: {
collection: 'video',
via: 'owner'
}
}
}
// in models/Video.js
// video has one user
module.exports = {
attributes: {
owner: {
model: 'user'
}
}
}
I'm using the REST blueprints with a /v1 prefix. I'm trying to either override GET /v1/user/:id/video, or make a custom route to GET /v1/user/:id/myGetVideo
So I've tried the following:
find and findOne methods in VideoController.js and UserController.js. These don't trigger for GET /v1/user/:id/video - I guess because the many-to-one association is treated differently
creating a custom route
// in routes.js
module.exports.routes = {
'get /user/:id/myGetVideo': 'UserController.myGetVideo'
}
This doesn't trigger anything because of the namespace, but it does trigger /user/:id/myGetVideo as expected. I don't want to add /v1 namespace here b/c that will proliferate and become an issue to change versions.
So, how do I either override the method I want, or put it in the namespace? Overriding the first method seems cleaner, but idk.
Thanks for any help!
Edit: Any comments on what is better practice for a REST API?
Got it with wildcards:
// in routes.js
module.exports.routes = { 'get /v*/user/:id/myGetVideo':'UserController.myGetVideo' }
not bullet-proof if the prefix scheme changes, but good enough