Graphul
Build web services and save money
A Rust framework that is memory safe, reliable, concurrent, and performant.
cargo add graphul
- Routing
- Serve Static Files
- Middleware Support
- Template Engines
- WebSocket Support
- Rate Limiter
Robust Routing
Setting up routes for your application has never been so easy! The Express-like route definitions are easy to understand and work with.
As an example, consider these simple routes:
You set a endpoint with Graphul
instance, acceding a function with the name of a HTTP method.
In this case we set a endpoint with app.get
, we pass the path and a function to execute as parameters.
Besides we can get a param by route (line 5) and we access to the param by the Context
app.get("/", || async {
"GET request"
})
app.get("/:param", |c: Context| async move {
format!("param: {}", c.params("param"))
})
app.post("/", || async {
"POST request"
})
Serve Static Files
Serve your SPA (React, Vue, Svelte, Angular etc), static HTML, CSS, JavaScript and other kind of files with ease by defining static routes. You can also serve the contents of multiple directories on the same route!
app.static_files("/", "public", FolderConfig::default())
// => http://localhost:3000/hello.html
// => http://localhost:3000/js/jquery.js
// => http://localhost:3000/css/style.css
// single page application
app.static_files("/", "app/build", FolderConfig::spa())
Flexible Middleware Support
The flexible middleware system allows us to add additional behavior to request/response processing. Middleware can hook into an incoming request process, enabling us to modify requests as well as halt request processing to return a response early
Typically, middleware is involved in the following actions:
- Pre-process the Request
- Post-process a Response
- Modify application state
- Access external services (redis, logging, sessions)
Choose from a number of already existing middleware or create your own with simple steps, our middleware API allows plugins to provide lots of plug-and-play features for your site.
Easy integration with a lot of popular crates like Tracing, Diesel, SeaORM, utopia and more.
use graphul::{Req, middleware::{self, Next}, http::{response::Response,Methods}, Graphul};
async fn my_middleware( request: Req, next: Next ) -> Response {
let authenticated = false;
if !authenticated {
return Redirect::to("/login");
}
next.run(request).await
}
#[tokio::main]
async fn main() {
let mut app = Graphul::new();
app.get("/", || async {
"hello world!"
});
app.middleware(middleware::from_fn(my_middleware));
// routes out of the scope of the middleware
app.get("/login", || async {
"Login page"
});
app.run("127.0.0.1:8000").await;
}
Template Engines
Graphul supports multiple template engines, one the most popular Askama but you can use others after all, the style of templating you like to use varies from person to person.
A template engine is essentially: Data + Template = String!
.
So, any template engine can be supported as long as it can render the final string.
Typically, middleware is involved in the following actions:
use graphul::{ http::Methods, Context, Graphul, template::HtmlTemplate};
use askama::Template;
#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate {
name: String,
}
#[tokio::main]
async fn main() {
let mut app = Graphul::new();
app.get("/:name", |c: Context| async move {
let template = HelloTemplate { name: c.params("name") };
HtmlTemplate(template)
});
app.run("127.0.0.1:8000").await;
}
WebSocket Support
Use the power of WebSockets in your Graphul app! Build fast interactive user experiences with performance and scalability guaranteed.
async fn handle_socket(mut socket: WebSocket) {
if let Some(msg) = socket.recv().await {
if let Ok(msg) = msg {
match msg {
Message::Text(t) => {
println!("client sent str: {:?}", t);
}
Message::Binary(_) => {
println!("client sent binary data");
}
Message::Ping(_) => {
println!("socket ping");
}
Message::Pong(_) => {
println!("socket pong");
}
Message::Close(_) => {
println!("client disconnected");
return;
}
}
} else {
println!("client disconnected");
return;
}
}
loop {
if socket
.send(Message::Text(String::from("Hi!")))
.await
.is_err()
{
println!("client disconnected");
return;
}
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
}
}
Rate Limiter
Rate limiting is a strategy for limiting network traffic. It puts a cap on how often someone can repeat an action within a certain timeframe - for instance, trying to log in to an account
Rate limiting can help stop certain kinds of malicious bot activity. It can also reduce strain on web servers.
With Graphul, limiting repeated requests to public APIs and endpoints is very simple. No more abusive requests.
#[tokio::main]
async fn main() {
let mut app = Graphul::new();
app.get("/", || async {
"hello world!"
});
// 1000 requests per 10 seconds max
app.middleware(RateLimitLayer::new(
1000,
std::time::Duration::from_secs(10)
));
app.run("127.0.0.1:8000").await;
}
EXTENSIBLE
Gives you true flexibility by allowing use of any other libraries thanks to modular architecture.
Easy To Use
Simple, intuitive APIs make Graphul approachable, no matter your background.
Boilerplate Free
Spend your time writing code that really matters, and let Graphul generate the rest.
VERSATILE
An adaptable ecosystem that is a fully-fledged backbone for all kinds of server-side applications.
Low Memory Footprint
Graphul's low memory footprint without a GC allows you to implement features without worrying about how much memory your application will use. This allows you to focus on your application and its business logic, rather than technical particularities.
Rapid Programming
Take your idea and turn it into reality in no time! Thanks to the well-designed and easy-to-learn API, you can develop your application in record speed (especially if you're coming from an Express.js background).