POST (createOne) operation semantics behaviour for a resource that already exists
See original GitHub issueHi,
I am new to the library and have a query regarding the default semantics/behaviour of POST (createOne) in typeorm-crud.service.ts. This uses the save method on the typeorm repository, which means that if the resource already exists then existing property values are updated.
public async createOne(req: CrudRequest, dto: T): Promise<T> {
const entity = this.prepareEntityBeforeSave(dto, req.parsed.paramsFilter);
/* istanbul ignore if */
if (!entity) {
this.throwBadRequestException(`Empty data. Nothing to save.`);
}
return this.repo.save<any>(entity);
}
Does the crud library provide a way to override this behaviour so that if a resource already exists then a 409 error status is thrown?
I have included the source code below that I am using for my entity, controller and service…
Entity
@Entity('course', {schema: 'coursemanagement' })
export class Course {
@ApiModelProperty()
@IsDefined({ groups: [CREATE, UPDATE] })
@IsNumber({}, { always: true })
@Column('integer', {
name: 'CourseID',
nullable: false,
primary: true,
})
public CourseID: number = 0;
@ApiModelProperty()
@IsDefined({ groups: [CREATE, UPDATE] })
@IsString({ always: true })
@Column('character varying', {
length: 50,
name: 'CourseName',
nullable: false,
})
public CourseName: string = '';
}
export default Course;
Controller
import { Controller, Inject } from '@nestjs/common';
import { CourseService } from './course.service';
import { Crud, CrudController, Override, ParsedRequest, ParsedBody, CrudRequest } from '@nestjsx/crud';
import { Course } from './course.entity';
import { Logger } from 'winston';
@Crud({
model: {
type: Course,
},
params: {
id: {
field: 'CourseID',
type: 'number',
primary: true,
},
},
routes: {
only: [
'createOneBase',
'deleteOneBase',
'getManyBase',
'getOneBase',
'updateOneBase',
]
}
})
@Controller('course')
export class CourseController implements CrudController<Course> {
constructor(@Inject('winston') private readonly logger: Logger, public service: CourseService) {
}
/**
* Provide intellisense, see https://github.com/nestjsx/crud/wiki/Controllers#intellisense
*/
get base(): CrudController<Course> {
return this;
}
}
Service
import { InjectRepository } from '@nestjs/typeorm';
import { Logger } from 'winston';
import { TypeOrmCrudService } from '@nestjsx/crud-typeorm';
import { Course } from './course.entity';
import { CourseRepository} from './course.repository';
@Injectable()
export class CourseService extends TypeOrmCrudService<Course> {
constructor(@Inject('winston') private readonly logger: Logger,
@InjectRepository(CourseRepository) private readonly courseRepository: CourseRepository) {
super(courseRepository);
}
}
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:7 (1 by maintainers)
Top Results From Across the Web
Difference between PUT and POST in REST APIs
The POST method is used to request that the origin server accept the entity attached in the request as a new subordinate of...
Read more >Should HTTP PUT create a resource if it does not exist?
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific ...
Read more >Resources vs. RPC semantic - Medium
A resource is an object with a type, associated data, relationships to other resources, and a set of methods that operate on it....
Read more >Data Flows - Hitachi Vantara Knowledge
The data that is to be protected flows from a Source Node to a Destination ... Adopt the replication; Re-evaluate the replication if...
Read more >draft-ietf-simple-xcap-02
If the Request-URI identifies a document that already exists in the server, the PUT operation replaces that document with the content of the...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hey guys! I think this is not a case this library should handle. As for me it should be done by the validation layer (class-validator) which is used by crud library.
Here is some example of implementing such a kind of Unique validator. As you can see, it could be used not for just for checking primary keys uniqueness. Moreover such an approach does not require any modifications of this library at all.
This approach is flexible and works perfect.
Also note that it won’t work unless you set up DI container (
useContainer
from ‘class-validator’ package) as described hereAlthough I agree that most of the validation must be done in the validation layer, like uniqueness of a username or something like this, I don’t think we should reimplement the logic for checking if a primary key is unique or not.
That’s counter intuitive for most of the databases that provide CRUD capabilities and it’s a bug for me since when one calls the
createOne
method he does not expect to update a resource, he’s probably in the context of creating a new resource.I believe all of this could be resolved by changing the call to
save
method as pointed by OP for a call toinsert
method.