rust - 使用 Serde 序列化值时如何执行额外的数据库查询?

标签 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"
    }]
}

最佳答案

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

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

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

这还有一个巨大的好处,那就是更容易测试。


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

另见:

关于rust - 使用 Serde 序列化值时如何执行额外的数据库查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53015098/

相关文章:

rust - 为 Rust 的 hyper http crate 使用自定义传输器

rust - Rust 中引用与值的显式注释

json - 如何在不丢失任何值的情况下反序列化具有重复键的JSON?

json - 从 JSON 数组中选择键的子集

rust - 当Foobar具有正好一个字段时,直接将Vec <Foobar <T >>反序列化为Vec <T>

rust - 在 Rust 中处理多个 `Option<T>` 的惯用方法是什么?

unit-testing - 如何在 Rust 中模拟特定方法而不是所有方法?

rust - 如何检查字符串是否代表 float ?

json - 如何用 Rust 合并两个 JSON 对象?

serialization - 如何将 BSON 反序列化为通用对象?