# Easy-DB
**Easy-DB** is a lightweight, secure, and zero-boilerplate Rust library that instantly turns SQLite tables into a fully functional REST API. It comes with a built-in, type-safe client to streamline backend-frontend communication.
[](https://opensource.org/licenses/MIT)
---
## Features
- **Zero Boilerplate:** No need to define structs or extensive router configurations. Just define your SQL schema and go.
- **Instant CRUD:** Automatically generates GET, POST, PUT, and DELETE endpoints for every exposed table.
- **Secure by Design:**
- **SQL Injection Protection:** Uses parameterized queries (`?`) for all data values.
- **Identifier Sanitization:** Strictly validates table and column names to prevent identifier injection attacks.
- **Built-in Client:** Includes `EasyClient` to handle HTTP requests without manual overhead.
- **Advanced Querying:** Supports filtering and sorting via URL parameters out of the box.
- **CORS Enabled:** Ready for frontend integration (React, Vue, etc.).
---
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
easy-db = "0.2.1"
tokio = { version = "1.0", features = ["full"] }
serde_json = "1.0"
anyhow = "1.0"
```
---
## Quick Start
### Running Server and Client in a Single File
For testing or small applications, you can run the server in a background task and the client in the main thread using `tokio::spawn`. This allows you to run a complete system demo from a single file.
```rust
use easy_db::{EasyDB, EasyClient};
use serde_json::json;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let port = 9000;
// 1. Initialize Server in the background
let mut db = EasyDB::init("demo_db")?;
db.create_table("users", "id INTEGER PRIMARY KEY, name TEXT, age INTEGER")?;
// Start server as a background task
tokio::spawn(async move {
let _ = db.run_server(port).await;
});
// Wait a moment for the server to bind to the port
sleep(Duration::from_millis(500)).await;
// 2. Use the Client to interact with the server
let client = EasyClient::new("localhost", port);
// Create a record
client.post("users", json!({"name": "John Doe", "age": 30})).await?;
// Fetch records
let users = client.get("users", None).await?;
println!("Server Response: {}", users);
Ok(())
}
```
---
## API Reference
Once the server is running, the following endpoints are automatically generated for every table you create:
| **GET** | `/:table` | List records | `?col=val` (filter), `?_sort=col&_order=desc` |
| **POST** | `/:table` | Create record | JSON Object of the columns |
| **PUT** | `/:table/:id` | Update record | JSON Object of the columns to change |
| **DELETE** | `/:table/:id` | Delete record | None |
### Filtering & Sorting Example
To get users named "Alice", sorted by age descending:
`GET /users?name=Alice&_sort=age&_order=desc`
---
## Security
Easy-DB takes security seriously. Unlike many basic dynamic API generators, it prevents **Identifier Injection**:
1. **Whitelisting:** Table and column names are checked against a strict alphanumeric whitelist (`[a-zA-Z0-9_]`).
2. **Parameterized SQL:** All values provided by the client are handled via prepared statements (`?` placeholders), making standard SQL injection attacks impossible.
---
## License
This project is licensed under the MIT License.