0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

swift openapi generator を試してみた

Posted at

swift-openapi-generator とは?

Introducing Swift OpenAPI Generator より抜粋

image.png

Swift OpenAPI Generator is a SwiftPM plugin that takes an OpenAPI document and generates either the client code to perform HTTP calls or the server code to handle those calls. The generated code translates between a type‑safe representation of each operation’s input and output, and the underlying HTTP request and response.
So whether developing an app that serves as a client of GreetingService or implementing GreetingService itself, Swift OpenAPI Generator generates the networking code for you, allowing you to focus on the core logic.

[訳]
Swift OpenAPI Generator は SwiftPM プラグインで、OpenAPI ドキュメントを受け取り、HTTP 呼び出しを実行するクライアントコードか、それらの呼び出しを処理するサーバーコードを生成します。生成されたコードは、それぞれの操作の入力と出力の型安全な表現と、基礎となるHTTPリクエストとレスポンスの間で変換されます。
そのため、GreetingServiceのクライアントとして機能するアプリを開発する場合でも、GreetingService自体を実装する場合でも、Swift OpenAPI Generatorはあなたのためにネットワークコードを生成し、コアロジックに集中することができます。

swift-openapi-generator とは?(簡単に)

バックエンドとのインターフェイスとなるコード(APIClient)を自動生成してくれる便利なパッケージ

メリット

  • ビルド時にコードを自動生成してくれるため、APIドキュメント(openapi.yaml) と同期状態であることを保証できる
  • GitHubリポジトリにAPIClientコードをコミットせずに済む(自動生成されるため)

本記事の目的

  • iOS開発において注力するべきことは何なのかを考える
    • swift-openapi-generator から逆説的に考える

swift-openapi-generator をコードベースで考える

swift-openapi-generator は、openapi.yaml をもとにコードを自動生成します。
そのため、まずは openapi.yaml について軽く説明します。説明後、本題である swift-openapi-generator について話します。

opneapi.yaml はAPIのリクエスト情報を記述したドキュメントです。
以下のような API があります。

ベースURL : http://localhost:8080
パス : /greet
 
HTTPメソッド : GET
クエリパラメータ : name(String)

openapi で記述すると、以下のようになります

openapi.yml
openapi: '3.0.3'
info:
  title: GreetingService
  version: 1.0.0
servers:
  - url: "http://localhost:8080" → ベースURL
    description: "Localhost"
paths:
  /greet: → パス
    get:  → HTTPメソッド
      operationId: getGreeting
      parameters: → クエリパラメータ
        - name: name
          in: query
          schema:
            type: string
      responses:
        '200':
          description: A success response with a greeting.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Greeting"
components:
  schemas:
    Greeting:
      properties:
        message:
          type: string
      required:
        - message

次に、swift-openapi-generator でコードを自動生成していきます。
はじめに 3つのパッケージをSPMでインストールします。

  1. swift-openapi-generator : コードを生成するための主なロジック
    • Target を None にして表示される2つのパッケージ選択
  2. swift-openapi-runtime :  生成されたコードから使用される、共通の型や抽象化を提供
  3. swift-openapi-urlsession : generatorが生成したコードとURLSessinoを紐付ける

次に、Build Phases > Run Build Tool Plug-ins に "OpenAPIGenerator"を追加。これをしないと、パッケージをimportするときに、パッケージエラー出ます。

image.png

openapi-generator-config.yml を作成し、プロジェクト配下に置く
生成されるコードのカスタマイズ設定が記述される。ServerSideSwift 使わないなら以下のままで良い。

openapi-generator-config.yml
generate:
    - types
    - client

openapi を使ったAPIクライアントの実装を書いておきます(参考

OpenAPIClient.swift

import Foundation
import OpenAPIRuntime
import OpenAPIURLSession

final class OpenAPIClient {
    let client: Client
    init() {
        self.client = .init(
            // クライアントも自動生成されたものを使える
            serverURL: try! Servers.server1(),
            transport: URLSessionTransport()
        )
    }

    func greet() async throws {
        // APIリクエスト
        let response = try await client.getGreeting(
            .init(query: .init(name: "hogehoge"))
        )

        // レスポンスをもとに条件分岐
        switch response {
        case .ok(let value):
            switch value.body {
            // レスポンスのbodyから greeting を抽出する
            case .json(let greeting):
                let message = greeting.message
            }
        case .undocumented(statusCode: let statusCode, _):
            print(statusCode)
        }
    }

    /// APIのレスポンスをViewで扱う型(ContentViewState)に変換する
    func greetTranslator(greeting: Components.Schemas.Greeting) -> ContentViewState {
        let newMessage = "Hello \(greeting.message)"
        return .init(message: greeting.message)
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?