Skip to content

Maintenance: replace EnvironmentVariablesService class with helper functions in Idempotency #4246

@dreamorosi

Description

@dreamorosi

Summary

In #3945 we added new zero-dependency functional utilities to read and parse environment variables. These new functions supersede the old class based environment service approach. We should refactor any use of the class based system to the new function based approach in the Idempotency utility.

The Idempotency package currently has its own EnvironmentVariablesService class that extends the common one and adds idempotency-specific methods. This class is used in two main places: IdempotencyConfig.ts for checking if idempotency is enabled, and BasePersistenceLayer.ts for getting the Lambda function name used in the idempotency key prefix.

Why is this needed?

The rationale for the introduction of these utilities as per #3945 is as follows:

Most of the advantage to customers will come in the form of smaller utilities over time, since we'll be able to use these helpers across other Powertools for AWS utilities and replace the existing EnvironmentVariablesService class-based model which is extremely verbose and requires props drilling if you want to access env variables deep into an inheritance stack.

This change will help us to eventually remove the EnvironmentVariablesService entirely from the code base. Additionally, this refactoring will:

  • Reduce complexity - Eliminates class inheritance and instantiation
  • Improve performance - Direct function calls instead of class method calls
  • Reduce bundle size - Removes dependency on the class-based service
  • Increase consistency - Aligns with the new functional approach across Powertools
  • Improve maintainability - Simpler code that's easier to understand and test

Which area does this relate to?

Idempotency

Solution

Important

The following changes are included as reference to help you understand the refactoring. Before implementing, please make sure to check the codebase and ensure that they make sense and they are exhaustive.

The idempotency package has its own EnvironmentVariablesService class in packages/idempotency/src/config/EnvironmentVariablesService.ts that extends the common one:

class EnvironmentVariablesService extends CommonEnvironmentVariablesService {
  private functionNameVariable = 'AWS_LAMBDA_FUNCTION_NAME';
  private idempotencyDisabledVariable = 'POWERTOOLS_IDEMPOTENCY_DISABLED';

  public getFunctionName(): string {
    return this.get(this.functionNameVariable);
  }

  public getIdempotencyEnabled(): boolean {
    return !this.isValueTrue(this.get(this.idempotencyDisabledVariable));
  }
}

Files that need changes

1. Delete packages/idempotency/src/config/EnvironmentVariablesService.ts

This entire file can be removed since we'll replace it with direct function calls.

2. Refactor packages/idempotency/src/IdempotencyConfig.ts

Current usage:

import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';

class IdempotencyConfig {
  readonly #envVarsService: EnvironmentVariablesService;
  readonly #enabled: boolean = true;

  public constructor(config: IdempotencyConfigOptions) {
    // ... other initialization
    this.#envVarsService = new EnvironmentVariablesService();
    this.#enabled = this.#envVarsService.getIdempotencyEnabled();
  }
}

Proposed refactoring:

import { getBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';

class IdempotencyConfig {
  readonly #enabled: boolean = true;

  public constructor(config: IdempotencyConfigOptions) {
    // ... other initialization
    this.#enabled = this.#getIdempotencyEnabled();
  }

  #getIdempotencyEnabled(): boolean {
    return !getBooleanFromEnv({
      key: 'POWERTOOLS_IDEMPOTENCY_DISABLED',
      defaultValue: false,
      extendedParsing: true,
    });
  }
}
3. Refactor packages/idempotency/src/persistence/BasePersistenceLayer.ts

Current usage:

import { EnvironmentVariablesService } from '../config/EnvironmentVariablesService.js';

abstract class BasePersistenceLayer {
  private envVarsService!: EnvironmentVariablesService;

  public constructor() {
    this.envVarsService = new EnvironmentVariablesService();
    this.idempotencyKeyPrefix = this.getEnvVarsService().getFunctionName();
  }

  private getEnvVarsService(): EnvironmentVariablesService {
    return this.envVarsService;
  }
}

Proposed refactoring:

import { getStringFromEnv } from '@aws-lambda-powertools/commons/utils/env';

abstract class BasePersistenceLayer {
  public constructor() {
    this.idempotencyKeyPrefix = this.#getFunctionName();
  }

  #getFunctionName(): string {
    return getStringFromEnv({
      key: 'AWS_LAMBDA_FUNCTION_NAME',
      errorMessage: 'AWS_LAMBDA_FUNCTION_NAME environment variable is required',
    });
  }
}

Environment Variables Used

  • POWERTOOLS_IDEMPOTENCY_DISABLED - Boolean flag to disable idempotency
  • AWS_LAMBDA_FUNCTION_NAME - Lambda function name used for idempotency key prefix

Acknowledgment

Future readers

Please react with 👍 and your use case to help us understand customer demand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmedThe scope is clear, ready for implementationgood-first-issueSomething that is suitable for those who want to start contributinghelp-wantedWe would really appreciate some support from community for this oneidempotencyThis item relates to the Idempotency Utility

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions