> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/charlietyn/openapi-generator/llms.txt
> Use this file to discover all available pages before exploring further.

# Environments

> Manage multiple deployment environments with hierarchical inheritance

## What Are Environments?

Environments represent different deployment contexts for your API (local, staging, production). The package uses environment configurations to:

* Generate Postman and Insomnia environment files
* Inject correct server URLs into OpenAPI specifications
* Support variable inheritance through parent-child relationships
* Track resource IDs across CRUD operation chains

<CardGroup cols={3}>
  <Card title="Base Environment" icon="database">
    Defines shared variables inherited by all environments
  </Card>

  <Card title="Sub-Environments" icon="layer-group">
    Specific configs for artisan, local, production
  </Card>

  <Card title="Tracking Variables" icon="link">
    Chain CRUD operations using resource IDs
  </Card>
</CardGroup>

## Configuration

Environments are configured in `config/openapi.php`:

```php theme={null}
'environments' => [
    'base' => [
        'name' => 'Base Environment',
        'variables' => [
            'base_url' => env('APP_URL', 'http://localhost:8000'),
            'token' => '',
            'api_key' => '',
        ],

        // GLOBAL tracking variables for CRUD chaining
        'tracking_variables' => [
            'last_user_id' => '',
            'last_role_id' => '',
            'last_permission_id' => '',
        ],
    ],

    'artisan' => [
        'name' => 'Artisan Environment',
        'parent' => 'base',
        'variables' => [
            'base_url' => 'http://127.0.0.1:8000',
            'api_key' => '__GENERATED__',
        ],
    ],

    'local' => [
        'name' => 'Local Environment',
        'parent' => 'base',
        'variables' => [
            'base_url' => 'http://localhost/${{projectName}}/public',
            'api_key' => '',
        ],
    ],

    'production' => [
        'name' => 'Production Environment',
        'parent' => 'base',
        'variables' => [
            'base_url' => 'http://${{projectName}}.com',
            'api_key' => '',
        ],
    ],
],
```

## Hierarchical Inheritance

### Base Environment

The `base` environment is the **parent** for all other environments. It defines:

* **Common variables** - Shared across all environments
* **Tracking variables** - GLOBAL variables for CRUD chaining

<Info>
  The `base` environment is never used directly. It only provides defaults for sub-environments.
</Info>

```php theme={null}
'base' => [
    'name' => 'Base Environment',
    'variables' => [
        'base_url' => env('APP_URL', 'http://localhost:8000'),
        'token' => '',
        'api_key' => '',
    ],
    'tracking_variables' => [
        'last_user_id' => '',
        'last_role_id' => '',
    ],
],
```

### Sub-Environments

Sub-environments inherit from `base` and override specific variables:

<Tabs>
  <Tab title="Artisan">
    Used with `php artisan serve`:

    ```php theme={null}
    'artisan' => [
        'name' => 'Artisan Environment',
        'parent' => 'base',  // Inherits from base
        'variables' => [
            'base_url' => 'http://127.0.0.1:8000',
            'api_key' => '__GENERATED__',
            // token is inherited from base
        ],
    ],
    ```

    **Final Variables:**

    ```json theme={null}
    {
      "base_url": "http://127.0.0.1:8000",
      "token": "",
      "api_key": "app_abc123...",
      "last_user_id": "",
      "last_role_id": ""
    }
    ```
  </Tab>

  <Tab title="Local">
    Used for local development (XAMPP, Valet, etc):

    ```php theme={null}
    'local' => [
        'name' => 'Local Environment',
        'parent' => 'base',
        'variables' => [
            'base_url' => 'http://localhost/${{projectName}}/public',
            'api_key' => '',
        ],
    ],
    ```

    **With Placeholder Replacement:**

    ```json theme={null}
    {
      "base_url": "http://localhost/my-app/public",
      "token": "",
      "api_key": "",
      "last_user_id": "",
      "last_role_id": ""
    }
    ```
  </Tab>

  <Tab title="Production">
    Used for production deployment:

    ```php theme={null}
    'production' => [
        'name' => 'Production Environment',
        'parent' => 'base',
        'variables' => [
            'base_url' => 'https://${{projectName}}.com',
            'api_key' => '',
        ],
    ],
    ```

    **With Placeholder Replacement:**

    ```json theme={null}
    {
      "base_url": "https://my-app.com",
      "token": "",
      "api_key": "",
      "last_user_id": "",
      "last_role_id": ""
    }
    ```
  </Tab>
</Tabs>

### Inheritance Logic

```php theme={null}
// From EnvironmentGenerator.php
protected function mergeVariables(array $config): array
{
    $variables = [];

    // If has parent, inherit variables
    if (isset($config['parent'])) {
        $parentConfig = config("openapi.environments.{$config['parent']}");

        if ($parentConfig) {
            // Inherit from parent
            $variables = array_merge(
                $parentConfig['variables'] ?? [],
                $parentConfig['tracking_variables'] ?? []
            );
        }
    }

    // Override with own variables
    $variables = array_merge($variables, $config['variables'] ?? []);

    return $variables;
}
```

## Tracking Variables

<Note>
  Tracking variables are **GLOBAL** variables that enable chaining CRUD operations in Postman and Insomnia.
</Note>

### What Are Tracking Variables?

Tracking variables automatically capture resource IDs from create/update operations and use them in subsequent show/update/delete requests.

**Example Flow:**

```
1. POST /users (Create User)
   Response: {"data": {"id": 42, "name": "John"}}
   → Stores 42 in {{last_user_id}}

2. GET /users/{{last_user_id}} (Show User)
   Request: GET /users/42
   → Uses the stored ID automatically

3. DELETE /users/{{last_user_id}} (Delete User)
   Request: DELETE /users/42
   → Uses the same stored ID
```

### Configuration

<Info>
  Tracking variables **MUST** be defined in the `base` environment only.
</Info>

```php theme={null}
'base' => [
    'tracking_variables' => [
        'last_user_id' => '',
        'last_role_id' => '',
        'last_permission_id' => '',
        'last_product_id' => '',
        'last_order_id' => '',
    ],
],
```

### Naming Convention

**Format:** `last_{resource_name}_id`

```php theme={null}
// For /users routes
'last_user_id' => '',

// For /products routes
'last_product_id' => '',

// For /api-apps routes
'last_api_app_id' => '',  // Use snake_case
```

### How It Works

The generator automatically uses tracking variables for CRUD operations:

```php theme={null}
// From OpenApiServices.php
protected function getVariableName(string $paramName, string $uri, string $actionType): string
{
    $structure = $this->parseUriStructure($uri);
    $resourceName = $structure['entity'];

    $crudActions = ['show', 'update', 'destroy', 'edit'];
    $isCrudAction = in_array(strtolower($actionType), $crudActions);

    $trackingVars = config('openapi.environments.base.tracking_variables', []);
    $globalVarName = 'last_' . Str::snake($resourceName) . '_id';
    $hasTracking = array_key_exists($globalVarName, $trackingVars);

    $isIdParam = in_array($paramName, ['id', $resourceName . '_id']);

    // Use GLOBAL variable for CRUD actions with tracking
    if ($isCrudAction && $hasTracking && $isIdParam) {
        return $globalVarName;  // → last_user_id
    }

    // Use LOCAL variable for other actions
    return $paramName;  // → id
}
```

### Generated Parameter References

<Tabs>
  <Tab title="With Tracking">
    For resources with tracking variables:

    ```json theme={null}
    {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "x-variable-name": "last_user_id",
          "schema": {"type": "integer"}
        }
      ]
    }
    ```

    **In Postman/Insomnia:**

    ```
    GET /users/{{last_user_id}}
    PUT /users/{{last_user_id}}
    DELETE /users/{{last_user_id}}
    ```
  </Tab>

  <Tab title="Without Tracking">
    For resources without tracking variables:

    ```json theme={null}
    {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "x-variable-name": "id",
          "schema": {"type": "integer"}
        }
      ]
    }
    ```

    **In Postman/Insomnia:**

    ```
    GET /webhooks/{{id}}
    PUT /webhooks/{{id}}
    DELETE /webhooks/{{id}}
    ```
  </Tab>
</Tabs>

## Placeholder Support

<Info>
  Use `${{placeholderName}}` syntax for dynamic values that are replaced during generation.
</Info>

### Available Placeholders

```php theme={null}
// From PlaceholderHelper.php
'${{projectName}}' → Project directory name (e.g., 'my-app')
'${{app_name}}' → APP_NAME from .env
'${{domain}}' → Derived from APP_URL
```

### Usage Examples

<Tabs>
  <Tab title="Server URLs">
    ```php theme={null}
    'servers' => [
        [
            'url' => 'https://localhost/${{projectName}}/public',
            'description' => 'Local Server',
        ],
        [
            'url' => 'https://${{projectName}}.com',
            'description' => 'Production Server',
        ],
    ],
    ```

    **After Replacement:**

    ```json theme={null}
    {
      "servers": [
        {
          "url": "https://localhost/my-app/public",
          "description": "Local Server"
        },
        {
          "url": "https://my-app.com",
          "description": "Production Server"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Environment Variables">
    ```php theme={null}
    'local' => [
        'variables' => [
            'base_url' => 'http://localhost/${{projectName}}/public',
            'api_key' => '${{app_name}}_local_key',
        ],
    ],
    ```

    **After Replacement:**

    ```json theme={null}
    {
      "base_url": "http://localhost/my-app/public",
      "api_key": "MyApp_local_key"
    }
    ```
  </Tab>
</Tabs>

## Generating Environment Files

### Postman Environments

```bash theme={null}
# Generate for specific environment
php artisan openapi:generate --format=postman --env=production

# Output includes separate environment JSON files
storage/app/public/openapi/
├── postman-collection.json
├── postman-env-artisan.json
├── postman-env-local.json
└── postman-env-production.json
```

**Generated Postman Environment:**

```json theme={null}
{
  "id": "postman-env-production",
  "name": "Production Environment",
  "values": [
    {
      "key": "base_url",
      "value": "https://my-app.com",
      "type": "default",
      "enabled": true
    },
    {
      "key": "token",
      "value": "",
      "type": "default",
      "enabled": true
    },
    {
      "key": "last_user_id",
      "value": "",
      "type": "default",
      "enabled": true
    }
  ],
  "_postman_variable_scope": "environment",
  "_postman_exported_at": "2024-03-07T10:30:00.000Z"
}
```

### Insomnia Environments

```bash theme={null}
php artisan openapi:generate --format=insomnia --env=local

# Output includes workspace with embedded environments
storage/app/public/openapi/
└── insomnia-workspace.json
```

**Generated Insomnia Workspace:**

```json theme={null}
{
  "_type": "export",
  "resources": [
    {
      "_id": "env_base_abc123",
      "_type": "environment",
      "name": "Base Environment",
      "data": {
        "base_url": "http://localhost:8000",
        "token": "",
        "last_user_id": ""
      }
    },
    {
      "_id": "env_local_def456",
      "_type": "environment",
      "parentId": "env_base_abc123",
      "name": "Local Environment",
      "data": {
        "base_url": "http://localhost/my-app/public"
      }
    }
  ]
}
```

## Adding Custom Environments

<Steps>
  <Step title="Define Environment">
    Add your environment to `config/openapi.php`:

    ```php theme={null}
    'environments' => [
        // ... existing environments
        
        'staging' => [
            'name' => 'Staging Environment',
            'parent' => 'base',
            'variables' => [
                'base_url' => 'https://staging.myapp.com',
                'api_key' => env('STAGING_API_KEY', ''),
            ],
        ],
    ],
    ```
  </Step>

  <Step title="Generate Documentation">
    ```bash theme={null}
    php artisan openapi:generate --env=staging
    ```

    The new environment will be included in generated Postman/Insomnia files.
  </Step>

  <Step title="Use in HTTP Endpoint">
    ```bash theme={null}
    curl "http://localhost:8000/documentation/openapi.json?env=staging"
    ```
  </Step>
</Steps>

## Best Practices

<Note>
  **Tracking Variables Location**

  * ALWAYS define `tracking_variables` in the `base` environment only
  * NEVER define them in sub-environments
  * They are automatically inherited by all sub-environments
</Note>

<Note>
  **Variable Naming**

  * Use descriptive names: `base_url` not just `url`
  * Follow snake\_case: `api_key` not `apiKey`
  * Tracking variables: always use `last_{resource}_id` format
</Note>

<Note>
  **Sensitive Values**

  * Use empty strings for secrets: `'api_key' => ''`
  * Users fill in values after importing
  * Use `env()` for development environments
</Note>

<Note>
  **Placeholder Usage**

  * Use for project-specific URLs
  * Avoid for user-specific values
  * Test placeholder replacement in generated files
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Postman Collections" icon="paper-plane" href="/guides/basic-usage">
    Learn how environments are used in Postman collections
  </Card>

  <Card title="Configuration Reference" icon="gear" href="/configuration/environments">
    Complete environment configuration options
  </Card>
</CardGroup>
