OpenAPITools / OpenAPITools/openapi-generator

[REQ] [Swift5] POP proposal

未关闭
#8,653 13 条评论 5 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Enhancement: Feature
主要语言
Java
星标
26.8k
派生
7.7k
PR 合并指标
PR 指标待抓取

描述

Hi guys,

I've been using the OpenAPI Generator for Swift 4/5 for a while now, quite happy with your work, thanks!

But after a while I struggled a bit whenever I needed to add some customisation on the generated code.
Mainly the issues I found were related to the fact that the methods are defined as class func.
That makes it hard to:

  • override: you would need to define a class SomethingSubclassAPI that inherits from the generated SomethingAPI class and override the method. Then you would need to use the subclass around. Easy to do if that happens at the beginning of the project, much more complicated if you already used a lot the generated class around
  • it forces you to pass through the same classes for all the calls, hence the problem above

I then modified the templates to achieve something different.

From this:

open class AlertAPI {
    /**
     Returns the alert
     
     - parameter ifNoneMatch: (header) The value of the Etag header returned in the previous response (optional)
     - parameter completion: completion handler to receive the data and the error objects
     */
    open class func getAlert(ifNoneMatch: String? = nil, completion: @escaping ((_ data: [Alert]?,_ error: Error?) -> Void)) {
        getAlertWithRequestBuilder(ifNoneMatch: ifNoneMatch).execute { (response, error) -> Void in
            completion(response?.body, error)
        }
    }
}

To this:

public protocol AlertAPIProtocol {
  /**
   Returns the alert
   
   - parameter ifNoneMatch: (header) The value of the Etag header returned in the previous response (optional)
   - parameter completion: completion handler to receive the data and the error objects
   */
   static func getAlert(ifNoneMatch: String?, completion: @escaping ((_ data: [Alert]?, _ headers:[String:String]?, _ error: Error?) -> Void))
}

public extension AlertAPIProtocol {

    static func getAlert(ifNoneMatch: String? = nil, completion: @escaping ((_ data: [Alert]?, _ headers:[String:String]?, _ error: Error?) -> Void)) {
        getAlertWithRequestBuilder(ifNoneMatch: ifNoneMatch).execute { (response, error) -> Void in
            completion(response?.body, response?.header, error)
        }
    }
}

This approach works quite well for me and it allows me to:

  • conform to the protocol in each class/struct/enum where I need to perform such API request
  • override the methods whenever and wherever I need to. I can override in a single case, if needed, or in a subprotocol, or even make conditional override based on conditions through the where operator
  • plug different protocols to the same class/struct/enum, composing different APIs by needs

Additionally I have an autogenerated Mock version of the same protocols, that inherits from the original ones, that load content from a json in the bundle. This approach opens to the possibility of conforming to AlertAPIPrototocol in a target and to AlertAPIMockPrototocol in another and being one a subprotocol to the other you can easily use polymorphism.
This is just an example of what this approach can lead to. :-)

I'd love to see this approach implemented in the official OpenAPI Generator for swift, I think it could be useful for a lot of people.
Are you interested on discussing this further?

Thanks,
Alessandro

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

检查 Swift 4/5 生成器模板,并将其当前生成的 API 类与 issue 中的 AlertAPI 和 AlertAPIProtocol 示例进行比较。与维护者明确预期范围,包括协议生成、自定义和 mock 支持。当约定的面向协议方法在 Swift 生成器中得到一致实现时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
swift
领域
tooling
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。