spring-petclinic/README.md
2026-02-08 18:02:36 +05:30

4 KiB
Raw Blame History

Feature Flag System - Spring PetClinic Integration

Overview

This project adds a custom-built Feature Flag system to the Spring PetClinic application without using any thirdparty feature flag libraries. The system allows runtime control of selected features using database-driven flags and an AOP-based custom annotation.

Features can be enabled/disabled globally and also support whitelist, blacklist, and percentage rollout strategies.


Tech Stack

  • Java 17+
  • Spring Boot 4.0.1 (Default version of Spring PetClinic)
  • Spring AOP
  • Spring Data JPA
  • MySQL
  • Maven

How To Run Locally

Clone Repo

You first need to clone the project locally:

git clone https://github.com/spring-projects/spring-petclinic.git
cd spring-petclinic

Database configuration

In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data.

A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed. Note that whenever the database type changes, the app needs to run with a different profile: spring.profiles.active=mysql for MySQL or spring.profiles.active=postgres for PostgreSQL. See the Spring Boot documentation for more detail on how to set the active profile.

I have used MySQL 8.0.34 for development and testing. For which I have added the following configuration to src/main/resources/application-mysql.properties:

spring.jpa.hibernate.ddl-auto=update

Before running the application with MySQL, make sure to create a database named petclinic if required.

Build & Run

You can start the application using maven on the command-line as follows:

./mvnw spring-boot:run

If you are using MySQL, you can start the application with the MySQL profile:

./mvnw spring-boot:run -Dspring-boot.run.profiles=mysql

You can then access the Petclinic at http://localhost:8080/.


Feature Flags Implemented

Feature Flag Name Location
Add Pet ADD_PET PetController POST processCreationForm
Add Visit ADD_VISIT VisitController POST processNewVisitForm
Owner Search OWNER_SEARCH OwnerController GET processFindForm

Each feature is protected using: @FeatureSwitch("FLAG_NAME")


Feature Flag Capabilities

Global Enable/Disable

Turns feature fully on/off.

Whitelist

Specific users always enabled.

Blacklist

Specific users always blocked.

Percentage Rollout

Deterministic hash-based rollout.


API — Feature Flag Management

Base Path: /api/flags

Create Flag

POST /api/flags

{ "flagName": "ADD_PET", "flagEnabled": true, "rolloutPercentage": 100 }

Returns 201 CREATED


List Flags

GET /api/flags


List Flag based on flag name

GET /api/flags/{name}

GET /api/flags


Delete Flag

DELETE /api/flags/{name}

Returns 204 NO CONTENT


Design Decisions

  • Built custom annotation + AOP instead of libraries (per requirement)
  • DB-backed persistence
  • Deterministic rollout using hash bucket
  • Default behavior = disabled if flag missing
  • No authentication on flag APIs (as per requirement)

Edge Cases Handled

  • Missing flag is treated as feature disabled
  • 0% rollout is treated as always blocked
  • 100% rollout is always enabled
  • Blacklist overrides whitelist

Package Structure (New Code)

The new code is placed in a separate package to maintain modularity and separation of concerns:

  • org.springframework.examples.petclinic.featureflags — Core feature flag system (annotation, aspect, service, repository)

Credits

Base project forked from:

Spring PetClinic — https://github.com/spring-projects/spring-petclinic

Feature Flag system implementation added as part of assignment work.