line / armeria

Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.
https://armeria.dev
Apache License 2.0
4.73k stars 899 forks source link

Provides a way for `DecoratorFactory` to be applied only once #5759

Open ikhoon opened 2 weeks ago

ikhoon commented 2 weeks ago

Say a decorator checks permission of request. I want to give all API write permissions in the class and optionally give read permissions. In this way, when a new API is added to the class, write permission is given by default. This will prevent the new API from being accidentally exposed with lower permissions.

This logic cannot be implemented using the DecoratorFactory. Because the decorators in the method and class are applied repeatedly even if it is the same class type.

In the SensitiveService, get() method can't be executed with READ permission. Both READ and WRITE are required instead.

@RequiresPermission(Permission.WRITE)
static class SensitiveService {
    @RequiresPermission(Permission.READ)
    @Get("/")
    public String get() { ... }

    @Post("/")
    public String create() { ... }

    @Put("/")
    public String update() { ... }
}

@DecoratorFactory(PermissionCheckerFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@interface RequiresPermission {
    Permission value() default Permission.READ;
}

enum Permission {
    READ, WRITE
}

To solve this case, I suggest adding the repeatable option to DecoratorFactory. If repeatable=false, the decorator with a higher priority will be selected.

public @interface DecoratorFactory {

    Class<? extends DecoratorFactoryFunction<?>> value();

    boolean repeatable() default true;
}

@DecoratorFactory(value = PermissionCheckerFactory.class, repeatable = false)
@Retention(RetentionPolicy.RUNTIME)
@interface RequiresPermission {
    Permission value() default Permission.READ;
}

If there is any other good name other than repeatable, please recommend it.

jrhee17 commented 2 weeks ago

Although not a widely used term, this kind of reminds me of additivity in the logging community. ref: https://logback.qos.ch/manual/architecture.html#additivity

seonWKim commented 2 weeks ago

I love the way the maintainers explain the details of the issue and extra information. Just reading the issues sometimes help me a lot 😄