Как выбрать результат запроса в JSON в Rust и Nickel?
Я использую nickel.rs:
router.get("/api/movies", middleware! { |request, response|
let mut test_movies =
r#"[
{ "title": "Ironman"},
{ "title": "The Walk"},
{ "title": "Paddington"}
]
"#;
let json = Json::from_str(test_movies);
format!("{}", json.unwrap())
});
Я хотел создать формат JSON. Код для подключения к PostgreSQL и преобразования в определение JSON приведен ниже:
extern crate rustc_serialize;
use rustc_serialize::json::{Json, Parser};
#[derive(RustcDecodable, RustcEncodable)]
struct Movie {
title: String,
}
И я попытался выбрать запрос и создать JSON
router.get("/api/movies", middleware! { |request, response|
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
let stmt = match conn.prepare("select title from movie") {
Ok(stmt) => stmt,
Err(e) => {
return response.send(format!("Preparing query failed: {}", e));
}
};
let res = match stmt.execute(&[]) {
Ok(v) => println!("Selecting movie was Success."),
Err(e) => println!("Selecting movie failed. => {:?}", e)
};
// ???
// let movies = Json::from_obj(res);
// let movies = request.json_as::<&[Movie]>().unwrap();
// let movies = request.json_as::Vec<Movie>().unwrap();
format!("{}", movies)
});
Однако я не знаю, как преобразовать результат в JSON.
let conn = conn.clone();
делает ошибки.
error: no method named `clone` found for type `postgres::Connection` in the current scope
я добавил
use nickel::status::StatusCode;
//use rustc_serialize::json::{Json, Parser};
use rustc_serialize::{json};
json::encode(&movies).unwrap();
была работа. но ноль вернулся...
в заключение
Я изменился execute
в query
а также использовать Vec<Movie>
,
let mut v: Vec<Movie> = vec![];
let movies = &conn.query("select title from movie", &[]).unwrap();
for row in movies {
let movie = Movie {
title: row.get(0),
};
v.push(movie);
}
let json_obj = json::encode(&v).unwrap();
response.set(MediaType::Json);
response.set(StatusCode::Ok);
return response.send(json_obj);
Я также определил struct
Moview как модель
struct Movie {
// id: i32,
title: String,
}
хм.. хлопотно много.
однако я не могу conn.clone()
еще.
1 ответ
Решение
Попробуйте следующее:
let json = json::encode(&res).unwrap();
response.set(MediaType::Json);
response.set(StatusCode::Ok);
return response.send(json);
Кроме того, неэффективно создавать новое соединение для каждого запроса. Вы можете создать одно соединение в функции main() и затем клонировать его внутри каждого закрытия запроса.
fn main(){
let mut server = Nickel::new();
let mut router = Nickel::router();
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
let shared_connection = Arc::new(conn);
{
let conn = shared_connection.clone();
router.get("/api/movies", middleware! ( |request, mut response|{
let mut v: Vec<Movie> = vec![];
let movies = &conn.query("select title", &[]).unwrap();
for row in movies {
let movie = Movie {
title: row.get(0),
};
v.push(movie);
}
let json_obj = json::encode(&v).unwrap();
res.set(MediaType::Json);
res.set(StatusCode::Ok);
return res.send(json_obj);
}));
}
{
let conn = shared_connection.clone();
router.post("/api/movies",middleware!(|request, mut response|{
//...
}));
}
server.utilize(router);
server.listen("127.0.0.1:6767");
}