cds-routing-handlers icon indicating copy to clipboard operation
cds-routing-handlers copied to clipboard

Abstract class with Handler or global handler

Open remde opened this issue 3 years ago • 5 comments

Hi,

I have a function that restricts access based on user permissions for a given entity. I'm calling this function before every entity's operations, such as:

@Handler(Entity)
export class EntityHandler {

    @BeforeCreate()
    @BeforeUpdate()
    @BeforeDelete()
    @BeforeRead()
    public async checkPermissions(@Req() req: Request): Promise<void> {
        await service.applyRestrictions(...);
    }
}

This means that these lines are repeated in every entity handler. I tried creating an AbstractHandler with this functionality and extending it in the entity's handlers, but it didn't work.

Is there any way to achieve what I want here? Perhaps with some other decorator, or with a global Handler behaviour?

Thanks in advance 😃

remde avatar Oct 28 '21 13:10 remde

Hi @remde,

have you already tried to register a middleware for this purpose? It should be possible to implement this with a middleware. You can also register a middleware explicitly for one entity only.

Regards Simon

HeneryHawk avatar Oct 28 '21 13:10 HeneryHawk

Hi @HeneryHawk, thanks for the quick answer.

I didn't find a way to implement different behaviours on the middleware depending on the operation. While I guess we can treat it differently depending on the req.event, I wonder if there is another way to do this.

Additionally, I didn't find a way to get parameters in the Middleware from the Handler in the way I would be able to with an abstract class, for instance. Is that possible? Say I have a HandlerMiddleware, is there a way to, in my Handler that @Use it, I pass an argument?

remde avatar Oct 28 '21 14:10 remde

Hi @remde,

you can also register the abstract class directly as a handler, but then it is not guaranteed that it is always executed in the first place.

I'm afraid it's currently not possible otherwise that you register in each handler a method for each operation and call a super method in it, or make a decision in a handler middleware depending on the req.event. I don't see any other possibility at the moment, sorry.

Regards Simon

HeneryHawk avatar Oct 28 '21 16:10 HeneryHawk

Seems good!

I believe passing parameters in the decorator is a good idea for the lib's roadmap 😃
I will be using what I can get from req, should suffice for my use case.

Thanks a lot!

remde avatar Oct 28 '21 17:10 remde

I'm trying to put some order into a CDS project, and your library helps a lot!

I stumbled upon this issue while working with aspects.

Let's say we have:

aspect Vehicle {
    action drive();
}
entity Car: Vehicle {}
entity Bicycle: Vehicle {}

How could I implement a single handler for the drive action? I was thinking to create a mixin handler and extend it, but I see cds-routing-handlers is using its own metadata storage which only checks the main class and not its parents.

Is it already possible to do this somehow? Or is it planned for the future? Can we help somehow?

alumni avatar Oct 24 '22 17:10 alumni