Как выбрать результат запроса в 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");
}
Другие вопросы по тегам