You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vapor 4:如何将预加载的父级关联关系映射为自定义公开格式

方案1:全场景适用,无侵入原有模型逻辑

这个方案不需要修改原有模型的默认编码规则,兼容需要返回私有字段的内部接口场景,同时样板代码极少。
第一步先定义公开的User DTO和便捷转换方法:

// 仅包含User的公开字段
struct PublicUser: Content {
    let id: UUID?
    let name: String
    let avatar: String?
}

// 给User加快速转换方法,后续User字段变更只需要维护这一处
extension User {
    var publicInfo: PublicUser {
        .init(
            id: id,
            name: name,
            avatar: avatar
        )
    }
}

第二步如果不想完整重写Course的所有属性DTO,可以用@dynamicMemberLookup减少样板代码:

@dynamicMemberLookup
struct PublicCourse: Content {
    private let base: Course
    let teacher: PublicUser

    init(_ course: Course) {
        self.base = course
        self.teacher = course.teacher.publicInfo
    }

    // 动态读取原有Course的属性,不需要重复定义
    subscript<T>(dynamicMember keyPath: KeyPath<Course, T>) -> T {
        base[keyPath: keyPath]
    }

    // 仅需要在这里维护需要对外返回的字段
    enum CodingKeys: String, CodingKey {
        case id, name, teacher
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        try container.encode(teacher, forKey: .teacher)
    }
}

最后修改路由的返回逻辑:

func list(req: Request) throws -> EventLoopFuture<[PublicCourse]> {
    return Course
        .query(on: req.db)
        .with(\.$teacher)
        .all()
        .map { $0.map(PublicCourse.init) }
}

这种方案后续Course新增公开字段时,只需要在CodingKeys和encode方法各加一行即可,不需要重复定义属性,维护成本极低。

方案2:所有User返回场景都不需要私有字段时使用,代码量最少

如果你不存在需要返回somePrivateField的接口场景,可以直接重写User的编码规则,完全不需要额外的DTO:

extension User {
    // 仅列出需要对外返回的字段,私有字段直接排除
    enum CodingKeys: String, CodingKey {
        case id, name, avatar
    }
}

修改后直接保留原有Course查询逻辑即可,预加载teacher后自动不会输出私有字段:

func list(req: Request) throws -> EventLoopFuture<[Course]> {
    return Course
        .query(on: req.db)
        .with(\.$teacher)
        .all()
}

高阶优化

如果项目模型多、场景复杂,可以使用Swift宏自动生成DTO和转换逻辑,完全消除样板代码,社区已有成熟的Vapor DTO生成宏可以直接使用。

内容的提问来源于stack exchange,提问作者Kevin Renskers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 13:48:03