OpenAPITools / OpenAPITools/openapi-generator

[REQ] [Swift5] POP proposal

オープン
#8,653 コメント 13 件 リアクション 5 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

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. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Swift 4/5 ジェネレーターのテンプレートを確認し、現在生成される API クラスと、issue にある AlertAPI および AlertAPIProtocol の例を比較します。プロトコル生成、カスタマイズ、モックサポートを含む意図したスコープをメンテナーと明確にします。合意したプロトコル指向のアプローチが Swift ジェネレーターに一貫して実装されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
swift
領域
tooling
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。