rust - 如何将JSON模式作为数据传递给Actix Web?

标签 rust jsonschema actix-web serde-json

我想将预编译的json模式传递给actix网站,但是编译器提示说,用来创建Value的借来的JSONSchema的生命周期不足。有办法解决此问题吗?
例子:

use jsonschema::JSONSchema;
use serde_json::from_str;
use actix_web::{web, get, App, HttpServer, HttpResponse, Responder};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        let schema_str = include_str!("schema.json");
        let schema_value = from_str(schema_str).unwrap();
        let schema_compiled = JSONSchema::compile(&schema_value).unwrap();
        App::new()
            .data(schema_compiled) // fixme: compiles if commented out
            .service(index)
    })
    .bind("0.0.0.0:8080")?
    .run()
    .await
}

#[get("/")]
async fn index<'a>(_schema: web::Data<JSONSchema<'a>>) -> impl Responder {
    HttpResponse::Ok().finish() // todo: use schema for something
}
rustc错误:
error[E0597]: `schema_value` does not live long enough
  --> src/main.rs:10:51
   |
10 |         let schema_compiled = JSONSchema::compile(&schema_value).unwrap();
   |                               --------------------^^^^^^^^^^^^^-
   |                               |                   |
   |                               |                   borrowed value does not live long enough
   |                               argument requires that `schema_value` is borrowed for `'static`
...
14 |     })
   |     - `schema_value` dropped here while still borrowed
我是使用rust 的新手,如果这是一个变相的通用使用rust 问题,我们深表歉意(一旦我的理解得到改善,将很高兴以较小的可复制性修改该问题)。

最佳答案

问题的根本原因是JSONSchema不拥有Value,但是我们可以解决此问题。首先,我们使用ValueBox::new放在堆栈上。然后,我们使用Box::leak泄漏引用(将在应用程序的整个生命周期内持续使用)。最后,我们使用Arc::new,以便我们可以在内部范围内的模式上调用clone()(这最后一步允许您将模式代码移动到其他位置,这很好)。

use jsonschema::JSONSchema;
use serde_json::{from_str, Value};
use actix_web::{web, get, App, HttpServer, HttpResponse, Responder};
use std::sync::Arc;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let schema_str = include_str!("schema.json");
    let schema_value:  &'static Value = Box::leak(Box::new(from_str(schema_str).unwrap()));
    let schema_compiled: JSONSchema<'static> = JSONSchema::compile(schema_value).unwrap();
    let schema_arc = Arc::new(schema_compiled);
    HttpServer::new(move || {
        App::new()
            .data(schema_arc.clone())
            .service(index)
    })
    .bind("0.0.0.0:8080")?
    .run()
    .await
}

#[get("/")]
async fn index<'a>(_schema: web::Data<Arc<JSONSchema<'a>>>) -> impl Responder {
    HttpResponse::Ok().finish() // todo: use schema for something
}

关于rust - 如何将JSON模式作为数据传递给Actix Web?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66231657/

相关文章:

windows - 为什么我不能从Actix文档样本中加载页面?

error-handling - Option<T> 的 map_err

json - 无效的 JSON 架构错误

rust - 确保 actix 按时间顺序记录//预处理

json - JSONConverter 的 Kafka Connect 架构格式

json - 类似字典的 JSON 模式

postgresql - 我无法捕获数据库引用

rust - 为什么在实现 From<&[u8]> 时需要生命周期

rust - 了解 &* 以访问 Rust Arc

rust - 无法构建交叉编译器