Testing & Debugging

Testing your Sling API specifications is a crucial step before deploying them in production. This document covers tools and techniques to verify your specs work correctly, debug issues, and optimize performance.

Content Overview

Testing Workflow

The general workflow for developing and testing API specs is:

Creating a Connection with an API Spec

The first step is create and save your Spec YAML file somewhere accessible. This can be your local drive, or any other be any storage connection you have setup, such a S3/GCP bucket, or FTP/SFTP. Furthermore, sling supports reading API Specs from a HTTP URL (such as Github URLs).

Once you have an API Spec file to use, you can then create a connection in your env.yaml file, like this:

connections:
  stripe:
    type: api
    # fetch from github repo
    spec: https://github.com/my-org/my-repo/blob/main/api/specs/stripe.yaml
    secrets:
      api_key: xxxxxxxxxxxxxxx

  my_api:
    type: api
    spec: file:///path/to/my_api.yaml  # read from local file
    secrets:
      account_id: xxxxxxxxxxx
      token: xxxxxxxxxxxxxxx

  my_other_api:
    type: api
    spec: aws_s3/path/to/my_other_api.yaml  # fetches from your s3 connection

You can also use an environment variable (YAML or JSON format):

# Windows Powershell
$env:DBT_CLOUD_API='{ type: api, spec: https://github.com/slingdata-io/sling-cli/blob/main/api/specs/dbt_cloud.yaml, secrets: { account_id: xxxxx, api_token: xxxxxxx } }'

# Linux or Mac
export DBT_CLOUD_API='{ type: api, spec: https://github.com/slingdata-io/sling-cli/blob/main/api/specs/dbt_cloud.yaml, secrets: { account_id: xxxxx, api_token: xxxxxxx } }'

The connection should show up like the others:

# List all your connections
$ sling conns list
+----------------+-----------------+----------------+
| CONN NAME      | CONN TYPE       | SOURCE         |
+----------------+-----------------+----------------+
| POSTGRES       | DB - PostgreSQL | sling env yaml |
| SNOWFLAKE      | DB - Snowflake  | sling env yaml |
| STRIPE         | API - Spec      | sling env yaml |
| MY_API         | API - Spec      | sling env yaml |
| MY_OTHER_API   | API - Spec      | sling env yaml |
| DBT_CLOUD_API  | API - Spec      | env variable   |
+----------------+-----------------+----------------+

Using the Test Command

Sling provides the conns test command to verify your API connection and test individual endpoints.

Testing the Connection

# Test that your connection is properly configured
sling conns test API_CONNECTION_NAME

# Example testing a Stripe connection
sling conns test STRIPE

Testing Specific Endpoints

# Test specific endpoints
sling conns test API_CONNECTION_NAME --endpoints endpoint1,endpoint2

# Example testing specific Stripe endpoints
sling conns test STRIPE --endpoints customer,charge

Discovering Available Endpoints

To see the available endpoints in your API spec:

# List all endpoints in your API spec
sling conns discover API_CONNECTION_NAME

# Example for Shopify
sling conns discover STRIPE

This command is particularly useful for verifying that all your endpoints are correctly defined and visible to Sling.

Debugging Tools

Sling offers two levels of debug output to help diagnose issues with your API specs.

Debug Flag

The --debug flag provides basic information about request flows, pagination, and data processing:

# Basic debugging information
sling conns test STRIPE --endpoints customer --debug

Debug output includes:

  • API requests being made

  • Response status codes

  • Record counts

  • Pagination details

  • State variable changes

Trace Flag

For more detailed debugging, use the --trace flag:

# Detailed trace information
sling conns test STRIPE --endpoints customer --trace

The trace output includes everything from debug plus:

  • Full request headers and parameters

  • Response headers

  • JSON response bodies (truncated for large responses)

  • Detailed expression evaluation

  • Auth token refresh events

  • Queue operations

⚠️ Warning: The --trace flag may expose sensitive information in logs, such as authorization tokens. Use carefully and don't share unredacted logs.

Examining Request and Response Flow

With trace enabled, you can see the complete flow of HTTP requests and responses. This is invaluable for debugging pagination, authentication, or data extraction issues:

2025-04-27 07:45:39 DBG iteration 1 initial state: {"base_url":"https://api.stripe.com/v1","created_gte":"1743158739","limit":100,"starting_after":null}
2025-04-27 07:45:39 DBG r.0001.jlw GET @ https://api.stripe.com/v1/customers?limit=100
2025-04-27 07:45:39 TRC r.0001.jlw request: {"method":"GET","url":"https://api.stripe.com/v1/customers?limit=100","headers":{"accept":"application/json","authorization":"Bearer xxxxxxxx","content-type":"application/json","stripe-version":"2023-10-16"},"payload":null,"attempts":1}
2025-04-27 07:45:40 DBG r.0001.jlw   response code=200 content-type=application/json duration=839ms size=36kB
2025-04-27 07:45:40 TRC r.0001.jlw response: {"headers":{"access-control-allow-credentials":"true","access-control-allow-methods":"GET, HEAD, PUT, PATCH, POST, DELETE","access-control-allow-origin":"*","access-control-expose-headers":"Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required","access-control-max-age":"300","cache-control":"no-cache, no-store","content-length":"35925","content-security-policy":"base-uri 'none'; default-src 'none'; form-action 'none'; frame-ancestors 'none'; img-src 'self'; script-src 'self' 'report-sample'; style-src 'self'; worker-src 'none'; upgrade-insecure-requests},"records":39,"size":35925,"status":200}
2025-04-27 07:45:40 DBG iteration 1 ending state: {"base_url":"https://api.stripe.com/v1","created_gte":"1743158739","last_id":"cus_xxxxxxxxxx","limit":100,"starting_after":null}

Common Issues

Authentication Problems

If you're getting 401 Unauthorized or 403 Forbidden responses:

# Check your authentication configuration
sling conns test API_NAME --debug

Common fixes:

  • Verify the secrets such as API keys or tokens in your environment file

  • Check for correct authentication type (bearer, basic, oauth2)

  • Ensure required scopes are included for OAuth2

Pagination Issues

If your endpoint doesn't retrieve all expected data:

# Trace pagination behavior
sling conns test API_NAME --endpoints ENDPOINT_NAME --trace

Look for:

  • stop_condition evaluation results

  • next_state changes between requests

  • Response headers for Link-based pagination

  • has_more flags in response bodies

JMESPath Extraction Problems

If your records aren't being properly extracted:

# Trace with attention to record extraction
sling conns test API_NAME --endpoints ENDPOINT_NAME --trace

Look for:

  • Complete response JSON to verify the correct path

  • JMESPath extraction results

  • Record counts in your output

Testing Best Practices

1. Test Incrementally

When building complex API specs:

  1. Start by testing basic authentication

  2. Test a simple endpoint without pagination

  3. Add and test pagination

  4. Test one endpoint that uses iteration

  5. Test queue-based workflows with multiple endpoints

  6. Finally, test complex transformations and processors

2. Limit Data During Testing

Use these techniques to limit data volume during testing:

Set the environment variable SLING_TEST_ENDPOINT_LIMIT:

# Windows Powershell
$env:SLING_TEST_ENDPOINT_LIMIT='30'

# Linux or Mac
export SLING_TEST_ENDPOINT_LIMIT=30
# In your endpoint definition
response:
  records:
    # Limit total records processed during testing
    limit: 10

Or use date filtering if the API supports it:

# Example from Shopify endpoint
request:
  parameters:
    # Limit to recent data only
    updated_at_min: '{date_format(date_add(now(), -2, "day"), "%Y-%m-%dT%H:%M:%S%z")}'

3. Use Replication Files for Full Testing

Create a replication YAML file to test the flow from API to your database:

# Example stripe_test.yaml
source: stripe_sling
target: postgres

defaults:
  mode: full-refresh  # Use for testing instead of incremental
  object: apis.stripe_test_{stream_name}  # Use test schema

streams:
  # Test specific streams
  customer:
  charge:

env:
  SLING_LOADED_AT_COLUMN: timestamp

Run with:

sling run -r stripe_test.yaml --debug

4. Create Environment Variables for Testing

For testing different scenarios:

# Test with different time ranges
CREATED_GTE=1659312000 sling conns test STRIPE --endpoints charge --debug

# Test with specific user
GITHUB_USERNAME=test-user sling conns test GITHUB --endpoints repos --debug

Real-World Examples

Testing Stripe Endpoints

This example tests the Stripe customer and balance transaction endpoints:

# Test specific Stripe endpoints
sling conns test STRIPE --endpoints customer,customer_balance_transaction --debug

The corresponding replication file would look like:

# r.61.stripe.yaml
source: stripe_sling
target: postgres

defaults:
  mode: incremental
  object: apis.{source_name}_{stream_name}

  source_options:
    flatten: 1 # flatten records 1 level only

streams:
  '*':

env:
  SLING_STATE: postgres/sling_state.stripe # one state table per replication
  SLING_LOADED_AT_COLUMN: timestamp

💡 Tip: When developing a complex API spec, maintain a test script with your commonly used test commands for quick iteration.

Last updated

Was this helpful?