Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Request metadata

Coordinate releases across services using request metadata passed in API calls, headers, or RPC messages. This strategy enables version management and backward compatibility without requiring consumers to use LaunchDarkly.

Overview

Request metadata allows API providers to make targeting decisions based on information passed in requests. This enables coordinated releases with external consumers and loosely coupled services without requiring all participants to integrate with LaunchDarkly.

When to use request metadata

Use request metadata when:

  • Services communicate via APIs, HTTP, or RPC
  • API consumers do not use LaunchDarkly
  • Services are in separate LaunchDarkly projects
  • Services need to maintain backward compatibility
  • Services have external or third-party consumers

How request metadata works

Each coordination strategy has two parts:

Platform

What teams do in LaunchDarkly: Create targeting rules based on API versions or client metadata to coordinate releases with external consumers.

Application

What developers implement:

Consumers attach metadata to requests through:

  • HTTP headers
  • Query parameters
  • Request body fields
  • RPC metadata

Providers use the metadata to define LaunchDarkly contexts for evaluation and targeting.

Request metadata scope

Request metadata works across boundaries:

ArchitectureSupported
Within a single projectYes
Across multiple projectsYes
Outside of projectsYes

Only the providing service needs to use LaunchDarkly. Consumers do not require LaunchDarkly integration.

Use cases

API version management

Manage breaking changes in public APIs by targeting based on API version.

Example scenario:

API service introduces breaking change to use UUID identifiers instead of integer IDs.

Setup:

  1. API consumers include version in header: X-API-Version: 2.0.0
  2. API service extracts version and creates context:
    const context = {
      kind: 'request',
      key: requestId,
      apiVersion: req.headers['x-api-version']
    };
    
  3. Create targeting rule: If apiVersion >= 2.0.0 then serve Available

Result:

Newer API clients automatically receive the new identifier format. Legacy clients continue using integer IDs until they upgrade.

Client-specific feature rollouts

Target features to specific mobile app versions or web browser versions.

Example scenario:

Mobile app releases new offline mode that requires minimum app version 3.5.0.

Setup:

  1. Mobile app includes version in API calls
  2. Backend service creates context with app version
  3. Create targeting rule: If appVersion >= 3.5.0 then serve Available

Result:

Backend enables offline sync features only for app versions that support offline mode.

Tenant-specific releases

Enable features for specific tenants in multi-tenant services.

Example scenario:

SaaS application wants to roll out advanced analytics to premium tier customers.

Setup:

  1. API gateway includes tenant information in header: X-Tenant-Id: acme-corp
  2. Backend service extracts tenant and subscription tier
  3. Create targeting rule: If subscriptionTier equals "premium" then serve Available

Result:

Premium tier customers see advanced analytics. Standard tier customers do not see the feature.

Implementation steps

Step 1: Define metadata schema

Determine what metadata consumers should provide:

  • API version
  • Client version
  • Client type (web, mobile, desktop)
  • Tenant identifier
  • User tier or subscription level

Step 2: Update API consumers

Instruct consumers to include metadata in requests:

HTTP headers:

X-API-Version: 2.1.0
X-Client-Type: mobile-ios
X-Client-Version: 3.5.2

Query parameters:

GET /api/widgets?api_version=2.1.0&client=mobile-ios

Request body:

{
  "data": { ... },
  "metadata": {
    "apiVersion": "2.1.0",
    "clientType": "mobile-ios"
  }
}

Step 3: Extract metadata in provider

Extract metadata from requests and create LaunchDarkly contexts:

Node.js example:

const express = require('express');
const { init } = require('@launchdarkly/node-server-sdk');

const app = express();
const ldClient = init(process.env.LD_SDK_KEY);

app.get('/api/widgets', async (req, res) => {
  // Extract metadata from request
  const apiVersion = req.headers['x-api-version'] || '1.0.0';
  const clientType = req.headers['x-client-type'] || 'unknown';

  // Create context for flag evaluation
  const context = {
    kind: 'request',
    key: req.requestId,
    apiVersion: apiVersion,
    clientType: clientType
  };

  // Evaluate feature flag
  const useNewFormat = await ldClient.variation(
    'use-new-response-format',
    context,
    false
  );

  // Return appropriate response
  if (useNewFormat) {
    res.json({ data: getNewFormatData() });
  } else {
    res.json({ data: getLegacyFormatData() });
  }
});

Step 4: Create targeting rules

Create targeting rules based on the extracted metadata:

  1. Navigate to the feature flag in LaunchDarkly
  2. Select the environment
  3. Create a new targeting rule
  4. Use the context attribute (for example, apiVersion)
  5. Configure the targeting logic (for example, apiVersion >= 2.0.0)
  6. Set the variation to serve
  7. Save the targeting rule

Step 5: Monitor and deprecate

Track usage of old API versions using flag evaluation metrics:

  1. Monitor which variations are being served
  2. Identify clients still using old versions
  3. Communicate deprecation timeline to affected clients
  4. Remove backward compatibility code when safe

Example configuration

Scenario: GraphQL API versioning

Context schema:

{
  "kind": "api-consumer",
  "key": "consumer-xyz",
  "apiVersion": "2023-11-01",
  "consumerType": "mobile-app",
  "consumerVersion": "4.2.0"
}

Targeting rules:

Flag: use-new-schema

Rule 1: Early access beta testers
  If consumerType equals "internal" then serve Available

Rule 2: New API version
  If apiVersion >= "2023-11-01" then serve Available

Rule 3: Opt-in consumers
  If consumer is one of ["consumer-abc", "consumer-xyz"] then serve Available

Default: Unavailable

Result:

  • Internal testers always get the new schema
  • Consumers using API version 2023-11-01 or later get the new schema
  • Specific consumers can opt in to the new schema early
  • All other consumers get the legacy schema

Best practices

Use semantic versioning

Use semantic versioning for API versions to enable meaningful comparisons:

  • Major version: Breaking changes
  • Minor version: Backward-compatible features
  • Patch version: Backward-compatible fixes

Document metadata requirements

Provide clear documentation for API consumers:

  • Required and optional metadata fields
  • Format and valid values
  • How metadata affects feature availability
  • Deprecation timelines

Provide defaults

Handle missing or invalid metadata gracefully:

const apiVersion = req.headers['x-api-version'] || '1.0.0';
const parsed = parseVersion(apiVersion) || { major: 1, minor: 0, patch: 0 };

Use flag statuses

Track deprecated API versions with flag statuses. Monitor usage to determine when old versions can be safely removed.

To learn more, read Flag statuses.

Communicate deprecation timelines

Provide advance notice to API consumers:

  • Include deprecation headers in API responses
  • Send notifications to registered consumers
  • Provide migration guides
  • Offer support during the transition

Example deprecation header:

Deprecation: version="1.0", date="2024-06-01"
Sunset: date="2024-12-01"
Link: <https://api.example.com/docs/migration-guide>; rel="deprecation"

Test with multiple client versions

Verify targeting rules work correctly for all supported client versions:

  1. Test with minimum supported version
  2. Test with latest version
  3. Test with versions at version boundaries
  4. Test with missing or invalid metadata

Troubleshooting

All clients receiving the same variation

Symptom: Targeting rules based on metadata do not differentiate between clients.

Possible causes:

  1. Metadata not being extracted from requests
  2. Context not being created with the correct attributes
  3. Targeting rules using incorrect attribute names

Solution:

  1. Log extracted metadata to verify it is present
  2. Verify context creation includes the expected attributes
  3. Check targeting rule attribute names match context attribute names

Legacy clients breaking after rollout

Symptom: Clients using old API versions receive errors or unexpected behavior.

Possible causes:

  1. Default variation serves new behavior
  2. Targeting rule comparison logic is incorrect
  3. Missing fallback handling for old versions

Solution:

  1. Ensure default variation serves legacy behavior
  2. Verify version comparison logic (for example, >= vs >)
  3. Add explicit targeting rules for old versions if needed

Combine request metadata with other coordination strategies:

  • Delegated authority: Grant API consumers permission to request custom targeting rules
  • Prerequisite flags: Use prerequisites for internal coordination while using request metadata for external coordination

To learn more about context attributes, read Contexts.