使用Serde序列化值时如何执行其他数据库查询?

时间:2018-10-26 19:21:23

标签: rust serde

ProgramProject有一对多关系。我正在寻找一种在打印JSON响应时将所有项目包含在程序中的理想方法。

extern crate rocket_contrib;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;

use rocket_contrib::Json;
use serde_json::Value;

mod schema {
    table! {
        projects (id) {
            id -> Int4,
            title -> Varchar,
            program_id -> Int4,
            is_archived -> Bool,
        }
    }

    table! {
        programs (id) {
            id -> Int4,
            title -> Varchar,
            is_archived -> Bool,
        }
    }
}

fn main() {
    let program = Program::get(id);
    let json_value = Json(json!({ "result": program }));
}

我研究了实现自定义序列化:

impl Serialize for Program {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
    }
}

但是我没有db::Conn来使用此功能提取项目。

我正在寻找类似的答复:

{ 
    "id": 1,
    "is_archived": false,
    "title": "Program 1",
    "projects": [{
      "id": 2,
      "is_archived": false,
       "title": "Project 1"
    }]
}

1 个答案:

答案 0 :(得分:1)

实际答案是不要。值的序列化不应涉及任意的数据库调用,而应仅序列化。创建一个结构来保存所有数据:

#[derive(Serialize)]
struct ProgramAndProjects {
    #[serde(flatten)]
    program: Program,
    projects: Vec<Project>,
}

然后编写一个函数,该函数通过执行所需的数据库查询来填充该结构并直接序列化结果。

这还有一个巨大的优势,那就是可以进行更广泛的测试。


话虽这么说,可能,但是这样做可能不值得。您可以将数据库连接插入 Program(或使用该连接和Program创建一个新类型),然后在序列化期间使用该连接。

另请参阅: