AWS Service Faking

Override individual AWS API operations with custom responses. Faked operations bypass the real emulation entirely — your code gets back exactly what you define.

Operation-Level Control

Fake specific operations like GetItem or ReceiveMessage while leaving the rest of the service running normally.

Service-Aware Helpers

Built-in helpers auto-format responses for each service — DynamoDB JSON, S3 XML, SQS message structures — so you don't have to.

How AWS Faking Works

1

Create a Fake

Create a named fake targeting a specific AWS service.

uvx --from local-web-services lws aws-fake create my-s3-fake --service s3
2

Add Operation Rules

Define what specific operations should return. Use service-aware helpers for correctly formatted responses.

# Fake a DynamoDB GetItem with a helper uvx --from local-web-services lws aws-fake add-operation my-ddb-fake \ --operation get-item \ --item '{"id": "123", "name": "test"}' # Fake an S3 GetObject with string content uvx --from local-web-services lws aws-fake add-operation my-s3-fake \ --operation get-object \ --body-string "Hello from S3" # Fake with a raw response uvx --from local-web-services lws aws-fake add-operation my-fake \ --operation list-objects-v2 \ --status 200 \ --body-file /path/to/response.xml
3

Requests Are Intercepted

When your code calls a faked operation, the fake middleware intercepts the request before it reaches the real provider and returns your custom response.

Supported Services

DynamoDB SQS S3 SNS EventBridge Step Functions Cognito SSM Secrets Manager IAM

Service-Aware Helpers

Helpers automatically format responses in the correct service-specific format.

DynamoDB

Helper Options

--item get-item query scan

Converts simple JSON to DynamoDB JSON format with type descriptors automatically. --item '{"id": "123", "age": 30}' becomes {"id": {"S": "123"}, "age": {"N": "30"}}.

S3

Helper Options

--body-string --body-file get-object list-objects-v2 head-object

Returns file content with proper headers (Content-Type, Content-Length, ETag). List operations generate correct S3 XML listings.

SQS, SSM, Secrets Manager, Cognito, SNS, Step Functions, EventBridge

Each service has helpers that format responses in the correct structure: SQS XML messages with auto-generated IDs, SSM parameter metadata, Cognito JWT tokens, SNS message IDs, Step Functions execution ARNs, and EventBridge entry responses.

Conditional Matching

Match requests by headers to return different responses for different inputs.

uvx --from local-web-services lws aws-fake add-operation my-s3-fake \ --operation get-object \ --match-header "x-custom-header=specific-value" \ --status 200 \ --body-string "Custom response for matched header"

YAML Configuration

AWS fakes are stored in .lws/fakes/<name>/ and loaded automatically on startup.

# .lws/fakes/my-s3-fake/config.yaml name: my-s3-fake service: s3 enabled: true
# .lws/fakes/my-s3-fake/operations/get-object.yaml operations: - operation: get-object match: headers: x-custom-header: "specific-value" response: status: 200 body: "file content" content_type: "text/plain" delay_ms: 100

Runtime Control

Enable and disable AWS fakes at runtime without restarting ldk dev.

# Enable/disable fakes for a service uvx --from local-web-services lws aws-fake enable s3 uvx --from local-web-services lws aws-fake disable s3 # Check fake status uvx --from local-web-services lws aws-fake status

External Service Faking

Create local fake servers for external API dependencies — payment processors, third-party services, partner APIs — so your entire application runs locally without any external calls.

$0

No API Costs

Stop burning through sandbox credits and rate limits during development. Fake servers return realistic responses without making real API calls.

No Credentials Needed

New developers don't need API keys for every third-party service. Fake servers work out of the box with zero configuration.

How External Faking Works

1

Create a Fake Server

Define a fake server for each external dependency. Give it a name and optional base configuration.

uvx --from local-web-services lws fake create --name stripe-api
2

Add Routes

Define the endpoints your code calls, with the responses you want returned. Use CLI commands or YAML configuration.

uvx --from local-web-services lws fake add-route \ --name stripe-api \ --method POST --path /v1/charges \ --status 200 \ --body '{"id": "ch_{{uuid}}", "status": "succeeded"}'
3

Start with ldk dev

Fake servers start automatically alongside your AWS services when you run ldk dev. Each fake gets its own local endpoint.

4

Point Your Code

Configure your application to use the local fake endpoint instead of the real API. Environment variables are injected automatically for services defined in your IaC.

Protocol Support

Fake servers support the protocols your external dependencies use.

REST

REST / HTTP

Full HTTP method support (GET, POST, PUT, PATCH, DELETE). Match requests by path, headers, query parameters, and body fields. Return custom status codes, headers, and JSON/text bodies.

GQL

GraphQL

Match GraphQL queries and mutations by operation name. Return typed response data with support for variables, nested objects, and error responses.

gRPC

gRPC

Define service methods and return protobuf-compatible JSON responses. Supports unary calls with status codes and metadata.

Defining Routes

Routes define how your fake server responds to incoming requests. Configure them via CLI or YAML.

Basic Route

routes: - method: POST path: /v1/charges status: 200 headers: Content-Type: application/json body: | { "id": "ch_{{uuid}}", "amount": {{body.amount}}, "currency": "{{body.currency}}", "status": "succeeded", "created": {{timestamp}} }

Conditional Matching

Routes can match on headers, query parameters, and body fields to return different responses for different inputs.

routes: # Match by header - method: GET path: /v1/customers match: headers: Authorization: "Bearer sk_test_valid" status: 200 body: '{"data": [{"id": "cus_123"}]}' # Match by query parameter - method: GET path: /v1/customers match: query: email: "not-found@example.com" status: 200 body: '{"data": []}' # Match by body field - method: POST path: /v1/charges match: body: amount: 99999 status: 402 body: '{"error": {"type": "card_error", "message": "Card declined"}}'

Template Variables

Use template variables in response bodies to generate dynamic, realistic responses.

Available Variables

Built-in Generators

{{uuid}} {{timestamp}} {{random_int(min,max)}} {{random_choice(a,b,c)}}

Request Data

{{path.paramName}} {{query.paramName}} {{header.name}} {{body.field}}

Example

routes: - method: POST path: /v1/payments status: 200 body: | { "id": "pay_{{uuid}}", "amount": {{body.amount}}, "currency": "{{body.currency}}", "status": "{{random_choice(succeeded,pending,requires_action)}}", "created": {{timestamp}}, "receipt_number": {{random_int(1000,9999)}} }

OpenAPI Import

Automatically generate fake routes from existing OpenAPI 3.x or Swagger 2.x specifications.

1

Import a Spec

Point lws fake import-spec at an OpenAPI file. Routes are generated for every endpoint with example responses from the spec.

uvx --from local-web-services lws fake import-spec \ --name stripe-api \ --spec openapi.yaml
2

Validate Coverage

Check that your fake covers all the endpoints your code actually calls. The validate command compares your fake routes against the spec and reports missing coverage.

uvx --from local-web-services lws fake validate \ --name stripe-api \ --spec openapi.yaml