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

Swift服务层默认给所有请求添加api_key的实现方案

如何为RequestModelProtocol设置默认api_key参数,避免重复编写

你的核心问题是当前请求模型直接覆盖了协议扩展的默认parameters,导致每次都要手动传入api_key。可以通过以下几种方式优化:

方案一:扩展协议,支持自定义参数与默认值合并

先修改协议,新增一个用于传递自定义参数的属性,然后在协议扩展中自动合并api_key:

protocol RequestModelProtocol {
    var baseUrl: String { get }
    // 新增自定义参数属性,默认返回空字典
    var customParameters: [String: Any] { get }
    var headers: [String: String]? { get }
    var method: HTTPMethod { get }
    var body: [String: Any]? { get }
}

extension RequestModelProtocol {
    var baseUrl: String {
        return MovieDBApiConstant.upcoming.rawValue
    }
    // 自动合并自定义参数和默认api_key
    var parameters: [String: Any] {
        var params = customParameters
        params["api_key"] = "594b8eb499******136ee3ed1ebdb"
        return params
    }
    var customParameters: [String: Any] {
        return [:]
    }
    var headers: [String: String]? {
        return ["accept": "application/json"]
    }
    var method: HTTPMethod {
        return .get
    }
    var body: [String: Any]? {
        return nil
    }
}

然后简化请求模型的实现,只需要处理baseUrl和可选的自定义参数:

struct UpcomingRequestModel: RequestModelProtocol {
    let baseUrl: String
    let customParameters: [String: Any]
    
    // 自定义参数默认是空字典,调用时可传可不传
    init(baseUrl: String, customParameters: [String: Any] = [:]) {
        self.baseUrl = baseUrl
        self.customParameters = customParameters
    }
}

调用时只传需要的自定义参数即可,api_key会自动加入:

func fetchUpcomingMovies() {
    dataProvider?.fetchUpcomingMovies(request: .init(
        baseUrl: MovieDBApiConstant.topRated.rawValue,
        customParameters: ["page": 1, "language": "EN"]
    ), completion: { response in
        switch response.result {
        case .success(let response):
            print("response: \(response)")
        case .failure(let error):
            print("err: \(error)")
        }
    })
}

方案二:不修改协议,直接在模型中合并参数

如果不想改动协议结构,可以在请求模型中重写parameters属性,手动合并协议扩展的默认参数和自定义参数:

struct UpcomingRequestModel: RequestModelProtocol {
    let baseUrl: String
    let customParams: [String: Any]
    
    init(baseUrl: String, customParams: [String: Any] = [:]) {
        self.baseUrl = baseUrl
        self.customParams = customParams
    }
    
    // 合并协议默认参数和自定义参数,自定义参数会覆盖重复的键(这里api_key不会被覆盖)
    var parameters: [String: Any] {
        var params = (self as RequestModelProtocol).parameters
        params.merge(customParams) { _, new in new }
        return params
    }
}

这种方式同样能实现自动带上api_key,调用时只需传自定义参数即可。

内容的提问来源于stack exchange,提问作者Ufuk Köşker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:05:18