Quick Start Tutorial

This tutorial walks you through creating various types of imposters with Rift.


Prerequisites

Ensure Rift is running:

docker run -p 2525:2525 ghcr.io/etacassiopeia/rift-proxy:latest

Basic REST API Mock

Create a mock for a simple user API:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4545,
    "protocol": "http",
    "name": "User API",
    "stubs": [
      {
        "predicates": [{ "equals": { "method": "GET", "path": "/users" } }],
        "responses": [{
          "is": {
            "statusCode": 200,
            "headers": { "Content-Type": "application/json" },
            "body": [
              { "id": 1, "name": "Alice" },
              { "id": 2, "name": "Bob" }
            ]
          }
        }]
      },
      {
        "predicates": [{ "equals": { "method": "GET", "path": "/users/1" } }],
        "responses": [{
          "is": {
            "statusCode": 200,
            "headers": { "Content-Type": "application/json" },
            "body": { "id": 1, "name": "Alice", "email": "alice@example.com" }
          }
        }]
      },
      {
        "predicates": [{ "equals": { "method": "POST", "path": "/users" } }],
        "responses": [{
          "is": {
            "statusCode": 201,
            "headers": { "Content-Type": "application/json" },
            "body": { "id": 3, "name": "New User" }
          }
        }]
      }
    ]
  }'

Test the endpoints:

# List users
curl http://localhost:4545/users
# [{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]

# Get user by ID
curl http://localhost:4545/users/1
# {"id":1,"name":"Alice","email":"alice@example.com"}

# Create user
curl -X POST http://localhost:4545/users -d '{"name":"Charlie"}'
# {"id":3,"name":"New User"}

Pattern Matching with Regex

Match dynamic paths using regex:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4546,
    "protocol": "http",
    "stubs": [{
      "predicates": [{
        "matches": {
          "path": "/users/\\d+"
        }
      }],
      "responses": [{
        "is": {
          "statusCode": 200,
          "body": { "message": "User found" }
        }
      }]
    }]
  }'
curl http://localhost:4546/users/123    # User found
curl http://localhost:4546/users/999    # User found
curl http://localhost:4546/users/abc    # No match (404)

JSON Body Matching

Match requests based on JSON body content:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4547,
    "protocol": "http",
    "stubs": [
      {
        "predicates": [{
          "equals": {
            "method": "POST",
            "body": { "action": "login", "username": "admin" }
          }
        }],
        "responses": [{
          "is": {
            "statusCode": 200,
            "body": { "token": "abc123", "role": "admin" }
          }
        }]
      },
      {
        "predicates": [{
          "contains": {
            "body": { "action": "login" }
          }
        }],
        "responses": [{
          "is": {
            "statusCode": 200,
            "body": { "token": "xyz789", "role": "user" }
          }
        }]
      }
    ]
  }'
# Admin login (exact match)
curl -X POST http://localhost:4547/login \
  -H "Content-Type: application/json" \
  -d '{"action":"login","username":"admin"}'
# {"token":"abc123","role":"admin"}

# Regular user login (contains match)
curl -X POST http://localhost:4547/login \
  -H "Content-Type: application/json" \
  -d '{"action":"login","username":"bob"}'
# {"token":"xyz789","role":"user"}

JSONPath Predicates

Match specific values in JSON using JSONPath:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4548,
    "protocol": "http",
    "stubs": [{
      "predicates": [{
        "jsonpath": { "selector": "$.order.total" },
        "equals": { "body": 100 }
      }],
      "responses": [{
        "is": {
          "statusCode": 200,
          "body": { "status": "approved", "discount": "10%" }
        }
      }]
    }]
  }'
curl -X POST http://localhost:4548/checkout \
  -H "Content-Type: application/json" \
  -d '{"order":{"items":["a","b"],"total":100}}'
# {"status":"approved","discount":"10%"}

Simulating Delays

Add latency to responses for testing timeouts:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4549,
    "protocol": "http",
    "stubs": [{
      "predicates": [{ "equals": { "path": "/slow" } }],
      "responses": [{
        "is": {
          "statusCode": 200,
          "body": "Response after delay"
        },
        "_behaviors": {
          "wait": 2000
        }
      }]
    }]
  }'
time curl http://localhost:4549/slow
# Response after delay
# real 0m2.015s

Error Simulation

Test error handling in your application:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4550,
    "protocol": "http",
    "stubs": [
      {
        "predicates": [{ "equals": { "path": "/error/400" } }],
        "responses": [{
          "is": {
            "statusCode": 400,
            "body": { "error": "Bad Request", "message": "Invalid input" }
          }
        }]
      },
      {
        "predicates": [{ "equals": { "path": "/error/500" } }],
        "responses": [{
          "is": {
            "statusCode": 500,
            "body": { "error": "Internal Server Error" }
          }
        }]
      },
      {
        "predicates": [{ "equals": { "path": "/error/503" } }],
        "responses": [{
          "is": {
            "statusCode": 503,
            "headers": { "Retry-After": "60" },
            "body": { "error": "Service Unavailable" }
          }
        }]
      }
    ]
  }'

Managing Imposters

List All Imposters

curl http://localhost:2525/imposters

Get Imposter Details

curl http://localhost:2525/imposters/4545

Delete an Imposter

curl -X DELETE http://localhost:2525/imposters/4545

Delete All Imposters

curl -X DELETE http://localhost:2525/imposters

Query Parameter Filtering

Match requests based on query parameters:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4551,
    "protocol": "http",
    "stubs": [
      {
        "predicates": [
          { "endsWith": { "path": "/tasks" } },
          { "equals": { "query": { "status": "OPEN" } } },
          { "deepEquals": { "method": "GET" } }
        ],
        "responses": [{
          "is": {
            "statusCode": 200,
            "body": { "count": 3, "tasks": [{"id": 1, "status": "OPEN"}] }
          }
        }]
      },
      {
        "predicates": [
          { "endsWith": { "path": "/tasks" } },
          { "equals": { "query": { "status": "CLOSED" } } },
          { "deepEquals": { "method": "GET" } }
        ],
        "responses": [{
          "is": {
            "statusCode": 200,
            "body": { "count": 0, "tasks": [] }
          }
        }]
      }
    ]
  }'
curl "http://localhost:4551/tasks?status=OPEN"
# {"count":3,"tasks":[{"id":1,"status":"OPEN"}]}

curl "http://localhost:4551/tasks?status=CLOSED"
# {"count":0,"tasks":[]}

Organizing Stubs with Scenarios

Use scenarioName to organize and document your stubs:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d '{
    "port": 4552,
    "protocol": "http",
    "name": "User Service",
    "allowCORS": true,
    "stubs": [
      {
        "scenarioName": "UserService-GetUser-Success",
        "predicates": [
          { "matches": { "path": "/users/\\d+" } },
          { "deepEquals": { "method": "GET" } }
        ],
        "responses": [{
          "is": {
            "statusCode": 200,
            "headers": { "Content-Type": "application/json" },
            "body": { "id": 1, "name": "Alice", "email": "alice@example.com" }
          }
        }]
      },
      {
        "scenarioName": "UserService-GetUser-NotFound",
        "predicates": [
          { "equals": { "path": "/users/999" } },
          { "deepEquals": { "method": "GET" } }
        ],
        "responses": [{
          "is": {
            "statusCode": 404,
            "headers": { "Content-Type": "application/json" },
            "body": { "error": "User not found", "code": "USER_NOT_FOUND" }
          }
        }]
      }
    ]
  }'

The scenarioName field helps identify which test scenario each stub supports.


CORS Support

Enable CORS for browser-based testing with allowCORS:

{
  "port": 4545,
  "protocol": "http",
  "allowCORS": true,
  "stubs": [...]
}

This automatically adds CORS headers to responses and handles preflight OPTIONS requests.


Example Files

Complete working examples are available in the examples/ directory:

File Description
basic-api.json Simple REST API with CRUD operations
error-testing.json Various HTTP error responses
latency-testing.json Latency simulation for timeout testing
task-management-api.json Complete task API with scenarios
feature-flags-api.json Feature toggle service mock
authentication-api.json Login/logout with token validation

Load an example:

curl -X POST http://localhost:2525/imposters \
  -H "Content-Type: application/json" \
  -d @examples/task-management-api.json

Managing Imposters

List All Imposters

curl http://localhost:2525/imposters

Get Imposter Details

curl http://localhost:2525/imposters/4545

Delete an Imposter

curl -X DELETE http://localhost:2525/imposters/4545

Delete All Imposters

curl -X DELETE http://localhost:2525/imposters

Next Steps