Quick Start Tutorial¶
This tutorial walks you through creating various types of imposters with Rift.
Prerequisites¶
Ensure Rift is running:
# The admin port plus the imposter ports this tutorial uses (4545-4552)
docker run -p 2525:2525 -p 4545-4552:4545-4552 zainalpour/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: 200 with an empty body (Mountebank behaviour)
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
}
}]
}]
}'
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¶
Get Imposter Details¶
Delete an Imposter¶
Delete All 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:
A CORS preflight (an OPTIONS carrying Origin, Access-Control-Request-Method and
Access-Control-Request-Headers) then gets those values echoed back as
Access-Control-Allow-Origin, -Methods and -Headers, on whatever the matching stub or
defaultResponse answers. Other requests get no CORS headers, so a browser's actual cross-origin
request still needs Access-Control-Allow-Origin in the stub's own headers, as with Mountebank.
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 from a checkout of the repository. The files use the {"imposters": [...]}
wrapper, so load them with PUT /imposters (which replaces every running imposter) or
--configfile, not POST.
curl -X PUT http://localhost:2525/imposters \
-H "Content-Type: application/json" \
-d @examples/task-management-api.json
Next Steps¶
- Predicates Reference - All predicate types
- Behaviors Guide - wait, decorate, copy
- Proxy Mode - Record and replay