Skip to content

Latest commit

 

History

History
133 lines (103 loc) · 3.73 KB

File metadata and controls

133 lines (103 loc) · 3.73 KB
title Access Environment Variables
id platform-environment-variables
skillLevel beginner
applicationPatternId platform-getting-started
summary Read environment variables safely with Effect Platform, handling missing values gracefully.
tags
platform
environment
config
getting-started
rule
description
Use Effect to access environment variables with proper error handling.
author PaulJPhilp
related
platform-hello-world
config-from-environment
lessonOrder 1

Guideline

Access environment variables using Effect's built-in functions or Platform's environment service for type-safe configuration.


Rationale

Environment variables can be missing or malformed. Effect helps you:

  1. Handle missing vars - Return Option or fail with typed error
  2. Validate values - Parse and validate with Schema
  3. Provide defaults - Fallback values when vars are missing
  4. Document requirements - Types show what's needed

Good Example

import { Effect, Config, Option } from "effect"

// ============================================
// BASIC: Read required variable
// ============================================

const getApiKey = Config.string("API_KEY")

const program1 = Effect.gen(function* () {
  const apiKey = yield* getApiKey
  yield* Effect.log(`API Key: ${apiKey.slice(0, 4)}...`)
})

// ============================================
// OPTIONAL: With default value
// ============================================

const getPort = Config.number("PORT").pipe(
  Config.withDefault(3000)
)

const program2 = Effect.gen(function* () {
  const port = yield* getPort
  yield* Effect.log(`Server will run on port ${port}`)
})

// ============================================
// OPTIONAL: Return Option instead of failing
// ============================================

const getOptionalFeature = Config.string("FEATURE_FLAG").pipe(
  Config.option
)

const program3 = Effect.gen(function* () {
  const feature = yield* getOptionalFeature
  
  if (Option.isSome(feature)) {
    yield* Effect.log(`Feature enabled: ${feature.value}`)
  } else {
    yield* Effect.log("Feature flag not set")
  }
})

// ============================================
// COMBINED: Multiple variables as config object
// ============================================

const AppConfig = Config.all({
  apiKey: Config.string("API_KEY"),
  apiUrl: Config.string("API_URL"),
  port: Config.number("PORT").pipe(Config.withDefault(3000)),
  debug: Config.boolean("DEBUG").pipe(Config.withDefault(false)),
})

const program4 = Effect.gen(function* () {
  const config = yield* AppConfig
  
  yield* Effect.log(`API URL: ${config.apiUrl}`)
  yield* Effect.log(`Port: ${config.port}`)
  yield* Effect.log(`Debug: ${config.debug}`)
})

// ============================================
// RUN: Will fail if required vars missing
// ============================================

Effect.runPromise(program4).catch((error) => {
  console.error("Missing required environment variables")
  console.error(error)
})

Config Types

Method Returns Behavior
Config.string(name) Config<string> Fails if missing
Config.number(name) Config<number> Fails if missing or NaN
Config.boolean(name) Config<boolean> Parses "true"/"false"
Config.withDefault(value) Config<A> Use default if missing
Config.option Config<Option<A>> None if missing
Config.all({...}) Config<{...}> Combine multiple

Best Practices

  1. Fail fast - Use required configs for critical values
  2. Provide defaults - Use withDefault for optional settings
  3. Validate early - Check config at startup, not runtime
  4. Document - Types show what environment vars are needed