Skip to content

Admin API ​

v0.2.0

FeatureFlagAdminModule provides a ready-made REST API for managing feature flags. It requires a guard to be injected — the module will not register without one.

Setup ​

typescript
import { FeatureFlagModule, FeatureFlagAdminModule } from '@nestarc/feature-flag';

@Module({
  imports: [
    FeatureFlagModule.forRoot({
      environment: 'production',
      prisma,
    }),
    FeatureFlagAdminModule.register({
      guard: AdminAuthGuard,
    }),
  ],
})
export class AppModule {}

Options ​

OptionTypeDefaultDescription
guardType<CanActivate>requiredNestJS guard applied to all admin endpoints
pathstring'feature-flags'Base route path for the admin API

WARNING

The guard option is required. Omitting it throws an error at startup. The package requires a guard class but does not implement authentication or authorization. Supply a guard that actually enforces administrator access.

Endpoints ​

All endpoints are prefixed with the configured path (default: /feature-flags).

Flags ​

MethodPathDescriptionError codes
POST/feature-flagsCreate a new flag409 duplicate key
GET/feature-flagsList all active flags—
GET/feature-flags/:keyGet a single flag404 not found
PATCH/feature-flags/:keyUpdate a flag404 not found
DELETE/feature-flags/:keyArchive a flag404 not found
POST/feature-flags/:key/evaluateEvaluate a boolean with context and optionsFallback details for missing/error evaluations

Overrides ​

MethodPathDescriptionError codes
POST/feature-flags/:key/overridesSet an override404 flag not found
DELETE/feature-flags/:key/overridesRemove an override404 flag not found

Usage Examples ​

Create a flag ​

bash
curl -X POST http://localhost:3000/feature-flags \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "key": "NEW_CHECKOUT",
    "description": "New checkout flow",
    "enabled": false,
    "percentage": 0
  }'

Start a 50% rollout ​

bash
curl -X PATCH http://localhost:3000/feature-flags/NEW_CHECKOUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "enabled": false,
    "percentage": 50
  }'

Set a tenant override ​

bash
curl -X POST http://localhost:3000/feature-flags/NEW_CHECKOUT/overrides \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "attributes": { "tenantId": "tenant-beta" },
    "enabled": true
  }'

Remove an override ​

bash
curl -X DELETE http://localhost:3000/feature-flags/NEW_CHECKOUT/overrides \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "attributes": { "tenantId": "tenant-beta" }
  }'

Archive a flag ​

bash
curl -X DELETE http://localhost:3000/feature-flags/OLD_FEATURE \
  -H "Authorization: Bearer <token>"

TIP

Archiving sets archivedAt on the flag. Archived flags always evaluate to false but remain in the database for audit purposes.

The examples require a guard that authenticates the supplied token and authorizes flag administration. With a partial rollout, supply a stable user/tenant key during evaluation. Keeping enabled: false gives contexts without a usable key an off fallback. See evaluation precedence. The override bodies use the 0.3+ attributes contract; top-level tenantId is rejected by the admin validation pipe.

Custom Guard Example ​

typescript
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class AdminAuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return request.user?.role === 'admin'; // request.user must already be authenticated.
  }
}

Released under the MIT License.