A flexible web framework that promotes stability, safety, security and speed.
Rust is a programming language that’s focused on safety, speed, and concurrency. It offers all the performance and control of a low-level language, but with the powerful abstractions of a high-level language.
Gotham targets stable Rust. This will never change.
Gotham is also automatically tested against Rust beta and nightly.
One of Rust’s key innovations is guaranteeing memory safety without requiring garbage collection. Gotham based applications automatically benefit from the predictability and performance of a system without garbage collection.
Unlike many other web frameworks Gotham is statically typed ensuring your entire application is correctly expressed at compile time.
Measure completed requests, including the 99th percentile, in µs.
A handler is a Rust function which generates a response to a HTTP request.
pub fn greet(state: State, _req: Request) -> (State, Response) {
let greeting = match GreetRequestPath::borrow_from(&state).name {
Some(ref name) => format!("Hello, {}!\n", name),
None => "Hello, world!\n".to_owned(),
};
let res = create_response(
&state,
StatusCode::Ok,
Some((greeting.into_bytes(), mime::TEXT_PLAIN)),
);
(state, res)
}
$ curl http://localhost:7878/greet
Hello, world!
$ curl http://localhost:7878/greet/Rustaceans
Hello, Rustaceans!
Extractors parse request data into type-safe structures provided by your application.
#[derive(StateData, FromState, PathExtractor, StaticResponseExtender)]
pub struct ChallengeRequestPath {
pub name: String,
}
#[derive(StateData, FromState, QueryStringExtractor, StaticResponseExtender)]
pub struct ChallengeQueryString {
pub count: Option<u8>,
}
pub fn index(state: State, _req: Request) -> (State, Response) {
let res = {
let crp = ChallengeRequestPath::borrow_from(&state);
let name = &crp.name;
let cqs = ChallengeQueryString::borrow_from(&state);
let count = cqs.count;
let hello = match count {
Some(count) => {
format!(
"Hello, {}.\nIzzy Mandelbaum can lift {} kgs, so more weight than you!!\n",
name,
count + 1
)
}
None => {
format!(
"Hello, {}.\nIzzy Mandelbaum can lift more weight than you.\n",
name
)
}
};
create_response(
&state,
StatusCode::Ok,
Some((hello.into_bytes(), mime::TEXT_PLAIN)),
)
};
(state, res)
}
Middleware can add functionality to your application without duplicating code.
// When defining a router, the middleware is added into a pipeline:
new_pipeline()
.add(
NewSessionMiddleware::default()
.with_session_type::<Session>()
)
// See our example app for a detailed example.
pub fn index(state: State, _req: Request) -> (State, Response) {
let response = {
// A value of type `SessionData<Session>` is added to `state` by the middleware
let session = SessionData::<Session>::borrow_from(&state);
create_response(
&state,
StatusCode::Ok,
Some((index_body(session.todo_list.clone()), mime::TEXT_HTML)),
)
};
(state, response)
}
A Gotham application compiles to a standard Rust binary.
pub fn main() {
let addr = "127.0.0.1:7878".parse().unwrap();
let server = Http::new()
.bind(&addr, NewHandlerService::new(router()))
.unwrap();
println!("Listening on http://{}", server.local_addr().unwrap());
server.run().unwrap();
}
$ cargo run
Compiling gotham-example-app v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 12.50 secs
Running `target/debug/gotham_example_app`
Listening on http://127.0.0.1:7878
Gotham is a young project that we want to create an energetic and respectful community around.
As a starting point we've adopted the following policies which we'd like your help in refining further.
These policies are in effect for any environment or tool that supports the Gotham project.
We collaborate via Gitter on the gotham-rs/gotham channel. Gotham specific chat and requests for help are both very welcome here.