Feature Flags with Spring Boot
Tags: features, spring, java
Published: 2021-09-07 13:57:14

Feature Flags is a very broad topic and have been coming back up regularly irrespective of what language you use. There are multiple platforms available which provide extensive support for managing your features external to the code or deployed as part of the code. Some of the examples are,
* LaunchDarkly
* Togglz
* Property (File) based
and many more.

## Table Of Contents
* [Problem at hand](#problem)
* [Project Setup] (#project)
* [Dependencies] (#dependencies)
* [Feature Loading] (#feature)
* [Enhancement] (#enhancement)
* [Remarks] (#remarks)


### Problem at hand <a name="problem"></a>
This article specifically targets a case where you can add a toggle check before any method you want before actually getting into the method execution. Be it at a controller level to prevent an API to be executed OR a service method OR a repository method. This pattern can be extended with any feature toggle implementation you use.

Code for the blog can be found here. {% github vikasgarghb/blog-feature-flags-spring no-readme %}

### Project Setup <a name="project"></a>
To begin with you will need,
* Java 11+
* Gradle 7+
* IDE of your choice
* Spring Boot 2.5.4+

### Dependencies <a name="dependencies"></a>
Apart from the other spring dependencies, you will need to include spring-aop and aspectjweaver. There are much documentation available for Aspect based programming with Spring. Won't go into much details about it. But one thing which this article focuses on is how aspect can be used to call a method before executing actual method.

AspectJ's `@Before` annotation allows us to accomplish this. As long as correct pointcut expression is provided, the method decorated with this annotation will be called before the actual method.

For eg,
```java
@Before("execution (* blog.vgarg.features..*(..)) && @annotation(checkFeatureFlag)")
public void checkFeatureFlag(JoinPoint joinPoint, CheckFeatureFlag checkFeatureFlag) {
    String flag = checkFeatureFlag.flag();
    if (!featureFlagService.isFeatureFlagSet(flag)) {
        throw new FeatureNotEnabledException();
    }
}
```

```java
@CheckFeatureFlag(flag = "flags.goodmorning")
@GetMapping("/good-morning")
public ResponseEntity<String> getGoodMorning() {
    return new ResponseEntity<>(greetingService.getGoodMorning(), HttpStatus.OK);
}
```

`checkFeatureFlag` method will be executed by spring before `getGoodMorning` method gets executed.

### Feature Loading <a name="feature"></a>
So, for this post, I am using file based features but the approach can be extended to use with any other feature provider.

```java
public interface FeatureFlagService {
    boolean isFeatureFlagSet(String flag);
}
```
I have defined an interface with a simple single method to check the status of any given feature flag. As mentioned for this post the implementation reads the toggle from a file named, `featureflags.properties` residing in `src/main/resources` (can be anywhere as long as it is on classpath).

### Enhancement <a name="enhancement"></a>
As mentioned before this can be extended for other feature support providers. For eg, with launch darkly the implementation will involve using the SDK provided by them. As long as the LD setup is done correct way, using their SDK is pretty simple. More can be read [here](https://docs.launchdarkly.com/sdk/server-side/java).

### Remarks <a name="remarks"></a>
This is very bare minimum implementation of the functionality and has the capability of being extended into more. This only applies when the feature check needs to be applied before the actual method. For eg, if a new API needs to be deployed but not released, this check can come in handy.

But as any other solution this is not one size fits all solution. Would be happy to hear from the community what solutions have they tried.