A powerful and flexible mock API server for rapid prototyping, testing, and development. JSON Echo allows you to create realistic API responses from simple JSON configuration files, making it perfect for frontend development, API testing, and service mocking.
- JSON-Based Configuration: Define routes and responses using intuitive JSON files
- Dynamic Route Handling: Support for parameterized routes with flexible data querying
- Static File Serving: Built-in static file serving for assets, images, and frontend files
- CORS Support: Built-in cross-origin resource sharing for web applications
- Async Performance: High-performance async server built with Tokio and Axum
- Type-Safe: Written in Rust with comprehensive error handling
- Auto-Discovery: Automatic project root detection and configuration file discovery
- Extensible: Modular architecture for easy customization and extension
git clone https://github.com/websublime/json-echo
cd json-echo
cargo build --release
The binary will be available at target/release/echo
.
cargo install --path .
echo init
This creates a json-echo.json
configuration file with default settings:
{
"port": 3001,
"hostname": "localhost",
"static_folder": "public",
"static_route": "/static",
"routes": {}
}
Edit the json-echo.json
file to define your mock API:
{
"port": 3001,
"hostname": "localhost",
"static_folder": "public",
"static_route": "/static",
"routes": {
"/api/users": {
"method": "GET",
"description": "Get all users",
"id_field": "id",
"response": {
"status": 200,
"body": [
{"id": 1, "name": "John Doe", "email": "john@example.com"},
{"id": 2, "name": "Jane Smith", "email": "jane@example.com"}
]
}
},
"[GET] /api/users/{id}": {
"description": "Get user by ID",
"id_field": "id",
"response": "users.json"
}
}
}
echo serve
Your mock API is now running at http://localhost:3001
!
--config <PATH>
: Path to configuration file (default:json-echo.json
)--log-level <LEVEL>
: Set logging level (trace
,debug
,info
,warn
,error
)--protocol <PROTOCOL>
: Network protocol (default:http
)
Initialize a new JSON Echo project with default configuration.
echo init
Options:
- Creates
json-echo.json
in the current directory - Sets up basic server configuration
- Ready for immediate customization
Start the mock API server with the specified configuration.
echo serve
Behavior:
- Loads configuration from the specified file
- Starts HTTP server on configured host and port
- Serves mock responses based on route definitions
- Supports hot-reloading during development
{
"port": 8080,
"hostname": "0.0.0.0",
"static_folder": "assets",
"static_route": "/public",
"routes": {
"/api/products": {
"method": "GET",
"description": "Product catalog",
"response": {
"status": 200,
"body": {
"products": [
{"id": 1, "name": "Laptop", "price": 999.99},
{"id": 2, "name": "Mouse", "price": 29.99}
],
"total": 2
}
}
},
"/api/health": {
"method": "GET",
"response": {
"status": 200,
"body": {"status": "ok", "timestamp": "2024-01-01T00:00:00Z"}
}
}
}
}
{
"routes": {
"/api/users": {
"method": "GET",
"response": "data/users.json"
},
"/api/posts": {
"method": "GET",
"response": "data/posts.json"
}
}
}
{
"static_folder": "www",
"static_route": "/assets",
"routes": {
"/api/users/{id}": {
"method": "GET",
"id_field": "user_id",
"results_field": "data",
"response": {
"status": 200,
"body": {
"data": [
{"user_id": 1, "name": "Alice"},
{"user_id": 2, "name": "Bob"}
]
}
}
}
}
}
{
"port": 3001,
"hostname": "localhost",
"static_folder": "public",
"static_route": "/static",
"routes": {
"/api/data": {
"method": "GET",
"response": {
"status": 200,
"body": {"message": "API endpoint"}
}
}
}
}
With this configuration:
- Static files in the
public/
folder are served at/static/*
public/index.html
becomes available athttp://localhost:3001/static/index.html
public/css/style.css
becomes available athttp://localhost:3001/static/css/style.css
- API routes continue to work normally
{
"routes": {
"[GET] /api/users": {
"response": "data/users.json"
},
"[POST] /api/users": {
"response": "data/users.json"
},
"[DELETE] /api/users/{id}": {
"response": "data/users.json"
},
}
}
With this configuration:
GET /api/users
returns the list of usersPOST /api/users
simulates user creationDELETE /api/users/{id}
simulates user deletion by ID
So you can use different HTTP methods for the same route path.
Once your server is running, you can make requests:
# Get all users
curl http://localhost:3001/api/users
# Get specific user by ID
curl http://localhost:3001/api/users/1
# Health check
curl http://localhost:3001/api/health
# Access static files
curl http://localhost:3001/static/index.html
curl http://localhost:3001/static/css/style.css
curl http://localhost:3001/static/images/logo.png
JSON Echo includes built-in static file serving capabilities, allowing you to serve assets, frontend applications, and other static content alongside your mock API endpoints.
Enable static file serving by adding two optional fields to your configuration:
{
"port": 3001,
"hostname": "localhost",
"static_folder": "public",
"static_route": "/static",
"routes": {
"/api/users": {
"method": "GET",
"response": {"status": 200, "body": []}
}
}
}
With the above configuration, organize your files like this:
your-project/
βββ json-echo.json # Configuration file
βββ public/ # Static files folder
β βββ index.html # Available at /static/index.html
β βββ css/
β β βββ style.css # Available at /static/css/style.css
β βββ js/
β β βββ app.js # Available at /static/js/app.js
β βββ images/
β βββ logo.png # Available at /static/images/logo.png
βββ data/
βββ users.json # For API responses
Mix static assets with API mocking during development:
{
"static_folder": "assets",
"static_route": "/assets",
"routes": {
"/api/config": {
"response": {"apiUrl": "http://localhost:3001", "environment": "development"}
}
}
}
Serve API documentation alongside mock endpoints:
{
"static_folder": "docs",
"static_route": "/docs",
"routes": {
"/api/openapi": {
"response": "openapi.json"
}
}
}
{
"static_folder": "web",
"static_route": "/app",
"routes": {}
}
Files in web/
folder become available at /app/*
URLs.
{
"static_folder": "build",
"static_route": "/",
"routes": {
"/api/*": "..."
}
}
Serves files at the root path while API routes are still available.
Static file serving supports all common file types:
- Web Assets:
.html
,.css
,.js
,.json
- Images:
.png
,.jpg
,.jpeg
,.gif
,.svg
,.ico
- Fonts:
.woff
,.woff2
,.ttf
,.otf
- Documents:
.pdf
,.txt
,.md
- Media:
.mp4
,.webm
,.mp3
,.wav
Content-Type headers are automatically set based on file extensions.
JSON Echo is built with a modular architecture:
json-echo/
βββ crates/
β βββ cli/ # Command-line interface
β βββ core/ # Core library functionality
βββ examples/ # Configuration examples
β βββ basic-api.json # Simple API example
β βββ external-files.json # External file references
β βββ data/ # Sample data files
βββ json-echo.json # Default configuration
βββ schema.json # JSON schema for validation
The json-echo-core
crate provides the foundational components:
- Configuration Management: JSON parsing and validation
- Database System: In-memory data storage and querying
- Filesystem Operations: Cross-platform file handling
- Error Handling: Comprehensive error types and propagation
For detailed API documentation and usage examples, see the Core Library README.
The json-echo-cli
crate provides the user-facing command-line interface:
- Argument Parsing: Command-line option handling
- Server Management: HTTP server lifecycle
- Route Handling: Dynamic route generation and request processing
- Middleware: CORS support and error handling
Field | Type | Default | Description |
---|---|---|---|
port |
number | 3001 |
Port number for the HTTP server |
hostname |
string | "localhost" |
Hostname or IP address to bind to |
static_folder |
string | null |
Relative folder path to serve static files from |
static_route |
string | "/static" |
Base route path for serving static files |
Field | Type | Required | Description |
---|---|---|---|
method |
string | No | HTTP method (default: "GET" ) |
description |
string | No | Human-readable route description |
headers |
object | No | Custom HTTP headers to include |
id_field |
string | No | Field name for unique identifiers (default: "id" ) |
results_field |
string | No | Field containing results when data is nested |
response |
object/string | Yes | Response configuration or file path |
Field | Type | Required | Description |
---|---|---|---|
status |
number | No | HTTP status code (default: 200 ) |
body |
any | No | Response body content |
# Use example configurations
echo --config examples/basic-api.json serve
# External file example
echo --config examples/external-files.json serve
# Custom configuration
echo --config my-custom-config.json serve
# Development with assets
echo --config dev-config.json serve
# Documentation site
echo --config docs-config.json serve
Example configurations:
spa-config.json - Serve SPA at root:
{
"port": 3000,
"static_folder": "dist",
"static_route": "/",
"routes": {
"/api/auth": {"response": {"token": "mock-token"}},
"[GET] /api/users": {"response": "data/users.json"}
}
}
dev-config.json - Development setup:
{
"static_folder": "public",
"static_route": "/assets",
"routes": {
"/api/config": {"response": {"env": "development"}},
"/api/data/{id}": {"response": "data/items.json"}
}
}
# Debug mode for development
echo --log-level debug serve
# Minimal logging for production
echo --log-level warn serve
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/echo /usr/local/bin/
COPY config.json /app/
COPY public/ /app/public/
COPY data/ /app/data/
WORKDIR /app
EXPOSE 3001
CMD ["echo", "serve"]
cargo test
cargo test -p json-echo-core --test config_tests
cargo test -p json-echo-core --test filesystem_tests
cargo test -p json-echo-core --test database_tests
Test your configuration with example requests:
# Test basic endpoint
curl -X GET http://localhost:3001/api/users
# Test parameterized endpoint
curl -X GET http://localhost:3001/api/users/1
# Test health check
curl -X GET http://localhost:3001/api/health
# Test static file serving
curl -X GET http://localhost:3001/static/index.html
curl -X GET http://localhost:3001/static/css/style.css
curl -I http://localhost:3001/static/images/logo.png
# Test CORS headers
curl -X OPTIONS http://localhost:3001/api/users \
-H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET"
# Test static files with CORS
curl -X OPTIONS http://localhost:3001/static/app.js \
-H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET"
Create a test directory structure:
mkdir -p public/{css,js,images}
echo "<h1>Hello World</h1>" > public/index.html
echo "body { margin: 0; }" > public/css/style.css
echo "console.log('Hello');" > public/js/app.js
Test configuration:
{
"static_folder": "public",
"static_route": "/static",
"routes": {
"/api/test": {"response": {"message": "API works"}}
}
}
Verify both API and static content:
# Test API endpoint
curl http://localhost:3001/api/test
# Test static files
curl http://localhost:3001/static/index.html
curl http://localhost:3001/static/css/style.css
curl http://localhost:3001/static/js/app.js
We welcome contributions! Please see our Contributing Guide for details.
- Clone the repository
- Install Rust (1.70.0 or later)
- Run tests:
cargo test
- Run the CLI:
cargo run --bin echo -- --help
- Follow Rust standard formatting:
cargo fmt
- Ensure clippy passes:
cargo clippy
- Add tests for new functionality
- Update documentation for API changes
This project is licensed under the MIT License - see the LICENSE file for details.
- Core Library Documentation
- Examples - Ready-to-use configuration examples
- JSON Schema - Configuration file validation schema
- Frontend Development: Mock backend APIs and serve static assets during frontend development
- API Testing: Create predictable responses for automated tests
- Prototyping: Quickly prototype API designs with static assets without full backend implementation
- Integration Testing: Mock external services in integration test suites
- Demo Applications: Provide realistic data and serve demo assets for presentations
- Development Workflows: Support offline development and testing with both API and static content
- Asset Testing: Test static asset delivery alongside API functionality
- Documentation: Check the Core Library README for detailed API documentation
- Examples: Check the examples directory for ready-to-use configurations
- Schema: Use the JSON schema for configuration validation in your editor
JSON Echo - Making API mocking simple, powerful, and developer-friendly.