| Crates.io | simple_json_server |
| lib.rs | simple_json_server |
| version | 1.0.2 |
| created_at | 2025-10-16 22:08:42.927149+00 |
| updated_at | 2025-10-16 22:36:17.826036+00 |
| description | A simple way to build a JSON-based server with automatic JSON serialization/deserialization, error handling, async support, type safety, and comprehensive RustDoc generation. |
| homepage | |
| repository | https://github.com/dcsturman/simple_json_server |
| max_upload_size | |
| id | 1886855 |
| size | 184,221 |
This library is intended to make it very easy to build a JSON-based server. Because its JSON it is easily called from multiple languages (think a TypeScript client). The goal is to provide a lot of functionality out of the box but with excellent ergonomics so that simple servers are easily built without almost any boilerplate.
This library is intended to make it very easy to build a JSON-based server. Because its JSON it is easily called from multiple languages (think a TypeScript client). The goal is to provide a lot of functionality out of the box but with excellent ergonomics so that simple servers are easily built without almost any boilerplate.
The macro both creates your simple server (an actor) from an impl of your struct and also generates documentation for your actor so its 100% clear how to call it.
The way simple_json_server works is:
Create a struct and create an impl block for it. The impl block should contain all the methods you want to expose on your server. The methods must be pub async fn and take &self as the first parameter. Others are ignored for this purpose.
The #[actor] macro will generate the code to make your struct into an actor. Each method in turn gets turned into a JSON-RPC where:
implThe create method will start a server for you and begin listening for incoming JSON-RPC calls via HTTP. create_ws will do the same but via WebSocket. Options for https and wss are also provided.
The easiest way to create an actor is using the #[actor] macro:
use simple_json_server::{Actor, actor};
#[derive(Debug, Clone)]
struct Calculator {
memory: f64,
}
impl Calculator {
fn new() -> Self {
Self { memory: 0.0 }
}
}
#[actor]
impl Calculator {
pub async fn add(&self, a: f64, b: f64) -> f64 {
a + b
}
pub async fn subtract(&self, a: f64, b: f64) -> f64 {
a - b
}
pub async fn get_memory(&self) -> f64 {
self.memory
}
}
fn main() {
let calc = Calculator::new();
calc.create(8080);
}
#[actor] MacroThe #[actor] procedural macro automatically implements the Actor trait for your struct by:
The macro only processes methods that are:
pub)async fn)Private methods and synchronous methods are ignored.
The library includes built-in HTTP and WebSocket server support. Use the create_options method to start a server.
Note: create and variants on create consumes the actor (moves it), preventing accidental use after starting the server. This is a safety feature that ensures the actor is only used within the server context.
use simple_json_server::{Actor, actor};
#[derive(Debug, Clone)]
struct MyActor {
name: String,
}
#[actor]
impl MyActor {
pub async fn greet(&self, name: String) -> String {
format!("Hello, {}! I'm {}", name, self.name)
}
}
fn main() {
// Create separate actor instances since create_options consumes the actor
let http_actor = MyActor { name: "HTTP-Server".to_string() };
let ws_actor = MyActor { name: "WebSocket-Server".to_string() };
// Start HTTP server on port 8080 (consumes http_actor)
http_actor.create(8080);
// Start WebSocket server on port 8081 (consumes ws_actor)
ws_actor.create_ws(8081);
// Keep main thread alive
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
The HTTP server expects POST requests with the method name in the URL path and parameters in the JSON body:
# Call the 'greet' method
curl -X POST http://127.0.0.1:8080/greet -d '{"name": "World"}'
The WebSocket server expects JSON messages in the standard format:
{"method": "greet", "params": {"name": "World"}}
The library supports secure connections using TLS for both HTTP (HTTPS) and WebSocket (WSS) protocols.
First, create a TlsConfig with your certificate and private key files:
use simple_json_server::{Actor, actor, TlsConfig};
let tls_config = TlsConfig::new("cert.pem", "key.pem");
// Start an HTTPS server
actor.create_https(8443, tls_config);
// Start a WSS server
actor.create_wss(8444, tls_config);
For development and testing, you can generate self-signed certificates:
# Use the provided script
./generate_cert.sh
# Or manually with OpenSSL
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
# Use -k flag to accept self-signed certificates
curl -k -X POST https://127.0.0.1:8443/greet -d '{"name": "World"}'
The TlsConfig struct supports:
There are examples in the simple_json_server crate itself. See the examples/ directory for a more complete (yet simple) demo. The demo will build on its own.
cd simple_json_server/examples
# Basic calculator example
cargo run --example calculator
# HTTP and WebSocket server example
cargo run --example server
# TLS/SSL server example (HTTPS and WSS)
cargo run --example tls_server
# The full example
cd ../../examples/demo
cargo run
The Actor trait defines two methods:
pub trait Actor {
/// Process a method call with parameters
fn dispatch(&self, method_name: &str, msg: &str) -> String;
/// Start a server (HTTP or WebSocket) on the specified port
/// This method consumes the actor, preventing further use after starting the server
fn create_options(self, port: u16, websocket: bool)
where
Self: Send + Sync + Sized + 'static;
}
If you need more control, you can implement the Actor trait manually instead of using the #[actor] macro.
The #[actor] macro automatically generates comprehensive RustDoc documentation for your Actor implementations. To view the generated documentation:
cargo doc --open
The generated documentation includes:
dispatchThis makes it easy to understand the JSON API without looking at the source code!