Last active
June 16, 2020 15:47
-
-
Save sayanarijit/658cae46e8dea26647ffee47f30c7e3f to your computer and use it in GitHub Desktop.
Rocket in a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "rocker_app" | |
version = "0.1.0" | |
authors = ["Arijit Basu <sayanarijit@gmail.com>"] | |
edition = "2018" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
rocket = "0.4.5" | |
serde = { version = "1.0", features = ["derive"] } | |
postgres = { version = "0.15", features = ["with-chrono", "with-uuid"] } | |
[dependencies.rocket_contrib] | |
version = "0.4.5" | |
default-features = false | |
features = ["json", "serve", "diesel_sqlite_pool", "diesel_postgres_pool", "redis_pool"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(proc_macro_hygiene, decl_macro)] | |
#[macro_use] extern crate rocket; | |
#[macro_use] extern crate rocket_contrib; | |
use serde::{Serialize, Deserialize}; // Helps with serializing and deserializing data | |
use rocket::Request; // The HTTP request | |
use rocket::uri; // Robust URL formatter | |
use rocket::http::RawStr; // Represents unvalidated data from URL params / POST data | |
use rocket::request::{Form, FromFormValue}; // Encodes/Decodes the RawStr to validated data structures | |
// use rocket::response::content; // Sets the Content-Type header | |
use rocket::response::status; // Sets the Status header | |
use rocket::fairing::AdHoc; // Allows attaching ad-hoc fairings | |
use rocket_contrib::databases::diesel; // ORM | |
use rocket_contrib::serve::StaticFiles; // Creates routes for serving static files | |
use rocket_contrib::json::Json; // JSON helper | |
// See Rocket.toml | |
#[database("sqlitedb")] | |
struct SQLiteDB(diesel::SqliteConnection); | |
// See Rocket.toml | |
#[database("pgdb")] | |
struct PGDB(diesel::PgConnection); | |
// A basic User schema | |
#[derive(FromForm, Serialize, Deserialize, UriDisplayQuery)] | |
struct User { | |
name: String, | |
account: usize, | |
} | |
// A wealthy User schema | |
#[derive(FromForm)] | |
struct WealthyUser { | |
name: String, | |
account: WealthyAccount, | |
} | |
struct WealthyAccount(usize); | |
impl<'v> FromFormValue<'v> for WealthyAccount { | |
type Error = &'v RawStr; | |
fn from_form_value(form_value: &'v RawStr) -> Result<WealthyAccount, &'v RawStr> { | |
match form_value.parse::<usize>() { | |
Ok(account) if account >= 1000 => Ok(WealthyAccount(account)), | |
_ => Err(form_value), | |
} | |
} | |
} | |
#[get("/")] | |
fn index(_db: SQLiteDB) -> &'static str { | |
// curl -si 'http://localhost:8000' | |
"Hello, world!" | |
} | |
#[get("/user?<id>&<user..>", rank = 2)] | |
fn user_get(_db: SQLiteDB, id: u8, user: Form<User>) -> String { | |
// Use Option<From<User>> or Result<From<User>> for error handling. | |
// curl -si 'http://localhost:8000/user?id=1&name=foo&account=1' | |
format!("Hello, {} ({}) [{}]", user.name, user.account, id) | |
} | |
#[get("/user?<id>&<user..>", rank = 1)] | |
fn user_get_wealthy(_db: SQLiteDB, id: u8, user: Form<WealthyUser>) -> Option<String> { | |
// curl -si 'http://localhost:8000/user?id=1&name=foo&account=1000' | |
// Return None to respond with 404 not found | |
Some(format!("Hello dear, {} ({}) [{}]", user.name, user.account.0, id)) | |
} | |
#[post("/user", data = "<user>", rank = 1)] | |
fn user_post(_db: SQLiteDB, user: Form<User>) -> status::Accepted<String> { | |
// curl -si 'http://localhost:8000/user' -X POST -d 'name=foo&account=122' | |
status::Accepted(Some(uri!(user_get: id = 1, user = user.0).to_string())) | |
} | |
#[post("/user", data = "<user>", format = "json", rank = 2)] | |
fn user_post_json( | |
_db: SQLiteDB, | |
user: Json<User> | |
) -> Result<status::Accepted<Json<User>>, status::BadRequest<Json<String>>> { | |
// curl -si 'http://localhost:8000/user' -X POST -d '{"name": "x", "account": 122}' -H 'Content-Type: application/json' | |
match user.name.len() { | |
0 => Err(status::BadRequest(Some(Json("Name cannot be empty".to_string())))), | |
_ => Ok(status::Accepted(Some(user))), | |
} | |
} | |
#[catch(404)] | |
fn not_found(req: &Request) -> status::NotFound<String> { | |
// curl -si 'http://localhost:8000/foo' | |
status::NotFound(format!("Sorry, '{}' is not a valid path.", req.uri())) | |
} | |
fn main() { | |
// TIP: For staging/productioon, run `ROCKET_ENV=<stage/prod> cargo run` | |
rocket::ignite() | |
.attach(SQLiteDB::fairing()) | |
// .attach(PGDB::fairing()) | |
.attach(AdHoc::on_launch("Custom Fairing", |_| { println!("Launching App") })) | |
.mount("/", routes![ | |
index, | |
user_get, | |
user_get_wealthy, // when account value >= 1000 | |
user_post, | |
user_post_json // When Content-Type: application/json | |
]) | |
.mount("/static", StaticFiles::from("./src/static")) | |
.register(catchers![not_found]) | |
.launch(); | |
} | |
#[cfg(test)] | |
mod test; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# TIP: Use `ROCKET_{VAR}` env vars to override. | |
# e.g. ROCKET_DATABASES={sqlitedb={url="foo.sqlite"}} cargo run | |
# [global.limits] | |
# json = 5242880 | |
# forms = 5242880 | |
[global.databases.sqlitedb] | |
url = "db.sqlite" | |
pool_size = 1 | |
[global.databases.pgdb] | |
url = "postgres://postgres:postgres@localhost:5432/db" | |
pool_size = 1 | |
[development] | |
address = "localhost" | |
port = 8000 | |
workers = 2 | |
keep_alive = 5 | |
log = "normal" | |
# secret_key = [randomly generated at launch] | |
[staging] | |
address = "0.0.0.0" | |
port = 8000 | |
workers = 4 | |
keep_alive = 5 | |
log = "normal" | |
# secret_key = [randomly generated at launch] | |
[production] | |
address = "0.0.0.0" | |
port = 8000 | |
workers = 4 | |
keep_alive = 5 | |
log = "critical" | |
# secret_key = [randomly generated at launch] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use super::*; | |
use rocket::local::Client; | |
use rocket::http::Status; | |
// TIP: Use `ROCKET_CODEGEN_DEBUG=1 cargo build` to expand code | |
#[test] | |
fn hello_world() { | |
let rocket = rocket::ignite().attach(SQLiteDB::fairing()).mount("/", routes![index]); | |
let client = Client::new(rocket).expect("valid rocket instance"); | |
let mut response = client.get("/").dispatch(); | |
assert_eq!(response.status(), Status::Ok); | |
assert_eq!(response.body_string(), Some("Hello, world!".into())); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment