目的
actix-webにあるサンプルに最小限でPostgreSQLを使えるように修正してみました。
example/r2d2を参考にしています。こちらはSQLLite。
プログラム
Cargo.toml
[package]
name = "web"
version = "0.1.0"
edition = "2018"
[dependencies]
actix-web = "^1.0"
futures = "0.1"
r2d2_postgres = "^0.14"
main.rs
use actix_web::{web, App, Error, HttpResponse, HttpServer};
use futures::Future;
use r2d2_postgres::{postgres, r2d2::Pool, PostgresConnectionManager, TlsMode};
fn index(
info: web::Path<(String, u32)>,
// コネクションをメソッドの引数でうけとる
db: web::Data<Pool<PostgresConnectionManager>>,
) -> impl Future<Item = HttpResponse, Error = Error> {
// DBの結果が返ってくるまでblock
web::block(move || {
let conn = db.get().unwrap();
let rows = conn.query("SELECT now()::TEXT", &[])?;
let row = rows.get(0);
let now: String = row.get(0);
// ここで戻り値の型を明示する必要がある
let result: Result<String, postgres::Error> = Ok(now);
result
})
.then(move |res| match res {
Ok(now) => {
Ok(HttpResponse::Ok().body(format!("Hello {}! id:{} now:{}", info.0, info.1, now)))
}
Err(_) => Ok(HttpResponse::InternalServerError().into()),
})
}
fn main() -> std::io::Result<()> {
// PostgreSQLのコネクションプールを作成する
let postgres_manager = PostgresConnectionManager::new(
"postgres://user:pass@localhost:5432/test",
TlsMode::None,
)
.unwrap();
let postgres_pool = Pool::builder().build(postgres_manager).unwrap();
HttpServer::new(move || {
App::new()
// Webデータとして設定
.data(postgres_pool.clone())
.service(web::resource("/{name}/{id}/index.html").to_async(index))
})
.bind("127.0.0.1:8080")?
.run()
}