| config | ||
| docs | ||
| examples | ||
| mocked | ||
| scripts | ||
| src | ||
| static/svgrepo.com | ||
| systemd | ||
| webapp/v1 | ||
| .gitignore | ||
| CLAUDE.md | ||
| CMakeLists.txt | ||
| install.md | ||
| Makefile | ||
| NOTES.md | ||
| notes.txt | ||
| README.md | ||
Mockita Storage API
A high-performance key-value storage API built with C++20, Drogon framework, and RocksDB.
Features
- Fast key-value storage powered by RocksDB
- RESTful API with JSON responses
- Webapp hosting with automatic API storage integration
- CORS support for web clients
- Configurable via JSON config file or command-line arguments
- Multi-threaded request handling
- Health check and statistics endpoints
Requirements
- C++20 compatible compiler (GCC 10+, Clang 10+)
- CMake 3.15+
- Dependencies (automatically built with
make install-local):- Drogon (web framework)
- RocksDB (storage engine)
- jsoncpp (JSON parsing)
- zlib, snappy, lz4, zstd (compression)
Quick Start
Build
# Install dependencies and build locally (no root required)
make install-local
make build-local
# Or with system-wide dependencies
make install
make build
Run
# Using default config (config/config.json)
make run-local
# Or run the binary directly
./build-local/mockita
# With custom config file
./build-local/mockita -c /path/to/config.json
# With command-line overrides
./build-local/mockita -p 9090 -d ./mydata -t 8
Configuration
Config File
The server looks for config/config.json by default. You can specify a different path with -c or --config.
Example config/config.json:
{
"app": {
"db_path": "./data/rocksdb",
"webapp_path": "./webapp/v1/index.html",
"threads": 0
},
"server": {
"address": "0.0.0.0",
"port": 8080,
"max_connections": 10000,
"max_connections_per_ip": 100,
"idle_timeout": 60
},
"logging": {
"path": "./logs",
"level": "info"
}
}
Configuration Options
App Section
| Option | Type | Default | Description |
|---|---|---|---|
db_path |
string | ./data/rocksdb |
Path to RocksDB database directory |
webapp_path |
string | ./webapp/v1/index.html |
Path to webapp HTML file |
threads |
int | 0 (auto) |
Number of worker threads. 0 = auto-detect CPU cores |
Server Section
| Option | Type | Default | Description |
|---|---|---|---|
address |
string | 0.0.0.0 |
IP address to bind to |
port |
int | 8080 |
Port to listen on |
max_connections |
int | 10000 |
Maximum total connections |
max_connections_per_ip |
int | 100 |
Maximum connections per IP address |
idle_timeout |
int | 60 |
Idle connection timeout in seconds |
Logging Section
| Option | Type | Default | Description |
|---|---|---|---|
path |
string | ./logs |
Directory for log files |
level |
string | info |
Log level: trace, debug, info, warn, error, fatal |
Command-Line Options
Command-line options override config file settings.
Usage: ./mockita [options]
Options:
-c, --config <path> Path to config file (default: config/config.json)
-d, --db <path> Database path (overrides config)
-p, --port <port> Server port (overrides config)
-t, --threads <num> Number of threads (overrides config)
-h, --help Show help message
Examples
# Use default config
./build-local/mockita
# Use custom config file
./build-local/mockita -c /etc/mockita/production.json
# Override port from config
./build-local/mockita -p 9090
# Override multiple settings
./build-local/mockita -p 9090 -d /var/lib/mockita/db -t 16
# Development mode with debug logging
# (create a config with logging.level = "debug")
./build-local/mockita -c config/development.json
Webapp Hosting
Mockita serves a webapp with backend storage integration. All data is persisted on the server via the API.
Webapp Endpoints
| Endpoint | Description |
|---|---|
GET / |
Creates new project & redirects to /{projectId} |
GET /{projectId} |
Serves the webapp with specific project (11 alphanumeric chars) |
Project URLs
Each visit to / creates a new project with a random 11-character ID:
http://localhost:8080/ -> Redirects to new project
http://localhost:8080/abc123XYZ99 -> Opens specific project
http://localhost:8080/MyProject01 -> Opens specific project
- Project ID must be exactly 11 characters (a-z, A-Z, 0-9)
- Data is stored at
/api/v1/project/{projectId} - Share the URL to let others access the same project
- Bookmark your project URL to return to it later
Example Projects
Upload example projects to see component usage in different syntax variants:
# Start the server first
make run-local
# Upload examples (in another terminal)
./scripts/upload-examples.sh
# Or specify a different host
./scripts/upload-examples.sh https://your-server.com
Each run creates new projects with random IDs (like user visiting home page):
Uploading examples to http://localhost:8888...
HTML Examples: http://localhost:8888/bbH0m6H1fGK
React Examples: http://localhost:8888/myaOqy17XqP
SwiftUI Examples: http://localhost:8888/Ljyj7kCvFEu
Adding more examples:
Edit the JSON files in examples/ directory:
examples/html-examples.json- Raw HTML component examplesexamples/react-examples.json- React/JSX syntax examplesexamples/swiftui-examples.json- SwiftUI-like DSL examples
To re-extract examples from the webapp source:
node scripts/extract-examples.js
Configuring Webapp Path
Set the path to your webapp HTML file in config/config.json:
{
"app": {
"webapp_path": "./webapp/v1/index.html"
}
}
API Reference
Base URL
http://localhost:8080/api/v1
Endpoints
Health Check
Check if the server is running.
GET /api/v1/health
Response:
{
"status": "healthy",
"service": "mockup-api",
"timestamp": 1703900000
}
Get Statistics
Get RocksDB statistics.
GET /api/v1/stats
Response:
{
"stats": "rocksdb.block.cache.miss COUNT : 0\n..."
}
Get Project
Retrieve a stored project by key.
GET /api/v1/project/{key}
Response (200 OK):
{
"key": "my-project",
"value": "{\"name\": \"My Project\", \"data\": {...}}"
}
Response (404 Not Found):
{
"error": "Project not found",
"key": "my-project"
}
Store Project
Store or update a project.
PUT /api/v1/project/{key}
Content-Type: application/json
{"name": "My Project", "data": {...}}
Response (201 Created):
{
"success": true,
"key": "my-project",
"size": 42
}
Delete Project
Delete a stored project.
DELETE /api/v1/project/{key}
Response (200 OK):
{
"success": true,
"key": "my-project"
}
CORS
All endpoints support CORS with the following headers:
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, PUT, DELETE, OPTIONSAccess-Control-Allow-Headers: Content-Type
Usage Examples
cURL
# Health check
curl http://localhost:8080/api/v1/health
# Store a project
curl -X PUT http://localhost:8080/api/v1/project/my-app \
-H "Content-Type: application/json" \
-d '{"name": "My App", "version": "1.0.0"}'
# Get a project
curl http://localhost:8080/api/v1/project/my-app
# Delete a project
curl -X DELETE http://localhost:8080/api/v1/project/my-app
# Get statistics
curl http://localhost:8080/api/v1/stats
JavaScript (Fetch API)
// Store a project
await fetch('http://localhost:8080/api/v1/project/my-app', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'My App', version: '1.0.0' })
});
// Get a project
const response = await fetch('http://localhost:8080/api/v1/project/my-app');
const data = await response.json();
console.log(data.value);
Python (requests)
import requests
# Store a project
requests.put(
'http://localhost:8080/api/v1/project/my-app',
json={'name': 'My App', 'version': '1.0.0'}
)
# Get a project
response = requests.get('http://localhost:8080/api/v1/project/my-app')
print(response.json())
Production Deployment
Option 1: Static Build (Recommended)
Build a single executable with minimal dependencies:
make prod
This creates dist/mockita - a portable binary that only requires these system libraries on the target:
- OpenSSL 3.x (
libssl.so.3,libcrypto.so.3) - libuuid (
libuuid.so.1) - libbrotli (
libbrotlidec.so.1,libbrotlienc.so.1) - glibc 2.17+ (
libc.so.6)
Copy to target and run:
scp dist/mockita user@server:/opt/mockita/
ssh user@server "/opt/mockita/mockita -c /etc/mockita/config.json"
Option 2: Bundle with Libraries
Create a self-contained distribution with all required libraries:
make bundle
This creates dist/mockita/ containing:
dist/mockita/
├── bin/mockita # The executable
├── lib/ # Required shared libraries
├── config/config.json
└── run.sh # Launch script (sets LD_LIBRARY_PATH)
Deploy the entire folder:
tar -czvf mockita.tar.gz -C dist mockita/
scp mockita.tar.gz user@server:/opt/
ssh user@server "cd /opt && tar -xzvf mockita.tar.gz && ./mockita/run.sh"
Option 3: Release Tarball
Create a release-ready tarball:
make dist
Uploading examples
make upload-examples HOST=http://localhost:8011 2>&1
Creates dist/mockita-x86_64-linux.tar.gz ready for distribution.
Make Targets
| Target | Description |
|---|---|
| Development | |
make install-local |
Install dependencies locally to ./deps |
make build-local |
Build using local dependencies |
make run-local |
Run the server with local libraries |
| Production | |
make prod |
Build static executable (single portable binary) |
make build-static |
Build with static linking |
make bundle |
Create distribution with binary + libraries |
make dist |
Create release tarball |
| System-wide | |
make install |
Install dependencies system-wide (requires sudo) |
make build |
Build using system dependencies |
make run |
Run the server |
| Utilities | |
make test |
Run API tests |
make clean |
Clean build artifacts |
make clean-all |
Clean everything including dependencies |
make clean-prod |
Clean production builds |
make help |
Show all available targets |
Project Structure
mockita/
├── config/
│ └── config.json # Default configuration
├── src/
│ ├── main.cpp # Application entry point
│ ├── controllers/
│ │ ├── ProjectController.h
│ │ └── ProjectController.cpp
│ └── storage/
│ ├── RocksDBStorage.h
│ └── RocksDBStorage.cpp
├── deps/ # Local dependencies (after make install-local)
├── build-local/ # Build output
├── data/ # RocksDB data directory
├── logs/ # Log files
├── CMakeLists.txt
├── Makefile
└── README.md
License
MIT License