0

我想使用 Rust 和 Juniper 创建一个 GraphQL 服务器。该服务器必须访问数据库。

我一直在尝试遵循Juniper 的这个示例代码,但它使用一个空Context来让给Schema; 我需要为数据库连接发送一个池。

我希望能够通过 和 websockets 连接到POSTGraphQL GET

type RepositoryPool = r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;

fn graphql(
    db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
    let state = warp::any().map(move || Context::new(db_pool.clone()));
    let root_node = Arc::new(schema());
    let graphql_filter = make_graphql_filter(schema(), state.boxed());

    let post_filter = warp::post()
        .and(warp::body::content_length_limit(1024 * 16))
        .and(graphql_filter.clone());

    let get_filter = warp::get().and(graphql_filter);

    let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
        let root_node = root_node.clone();
        let db_pool = db_pool.clone();
        ws.on_upgrade(move |websocket| async move {
            serve_graphql_ws(
                websocket,
                root_node,
                ConnectionConfig::new(Context::new(db_pool)),
            )
            .map(|r| {
                if let Err(e) = r {
                    println!("Websocket error: {}", e);
                }
            })
            .await
        })
    });

    warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}

但是,我收到一个错误:

error[E0382]: use of moved value: `db_pool`
  --> src\filters.rs:39:34
   |
27 |   db_pool: RepositoryPool,
   |   ------- move occurs because `db_pool` has type `r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>`, which does not implement the `Copy` trait
28 | ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
29 |   let state = warp::any().map(move || Context::new(db_pool.clone()));
   |                               -------              ------- variable moved due to use in closure
   |                               |
   |                               value moved into closure here
...
39 |   let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
40 |     let root_node = root_node.clone();
41 |     let db_pool = db_pool.clone();
   |                   ------- use occurs due to use in closure

move我对这些值解决这个问题的方式不够了解。我该如何解决这样的问题?

4

1 回答 1

0

感谢一些评论,我找到了 Rust 编译器接受的一种方式:

fn graphql(
    db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
    let db_pool_clone = db_pool.clone();
    let state = warp::any().map(move || Context::new(db_pool_clone.clone()));
    let root_node = Arc::new(schema());
    let graphql_filter = make_graphql_filter(schema(), state.boxed());

    let post_filter = warp::post()
        .and(warp::body::content_length_limit(1024 * 16))
        .and(graphql_filter.clone());

    let get_filter = warp::get().and(graphql_filter);

    let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
        let root_node = root_node.clone();
        let db_pool = db_pool.clone();
        ws.on_upgrade(move |websocket| async move {
            serve_graphql_ws(
                websocket,
                root_node,
                ConnectionConfig::new(Context::new(db_pool)),
            )
            .map(|r| {
                if let Err(e) = r {
                    println!("Websocket error: {}", e);
                }
            })
            .await
        })
    });

    warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}

我不完全理解为什么这是必要的,但它现在有效。

于 2020-10-26T16:54:47.870 回答