View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • サーバエコシステムでのSwiftの詳細

    Swiftはサーバアプリの記述に適している言語であり、Appleのさまざまなクラウド製品の重要なサービスをサポートしています。このセッションでは、ツールを紹介し、Swiftサーバパッケージエコシステムについて詳しく説明するとともに、データベースとのインタラクションを行う方法とアプリにオブザーバビリティを追加する方法をデモを交えて解説します。

    関連する章

    • 0:00 - Introduction
    • 0:13 - Agenda
    • 0:27 - Meet Swift on Server
    • 2:30 - Build a service
    • 3:46 - Swift OpenAPI generator
    • 5:42 - Database drivers
    • 10:53 - Observability
    • 15:19 - Explore the ecosystem
    • 16:12 - Wrap up

    リソース

    • Forum: Programming Languages
    • Swift on Server
    • Swift Package Ecosystem
    • Swift Server Workgroup
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC23

    • 構造化並行処理の基本を超えて
    • Swift OpenAPI Generatorの紹介
  • ダウンロード

    こんにちは Appleの Swift on ServerチームのFranzです 本セッションではサーバエコシステムでの Swiftの詳細について見ていきます まず Swiftがサーバアプリの開発に 非常に適した言語である理由を説明します 次に 人気のあるエコシステムの パッケージを使ってサービスを構築します

    最後に エコシステムの仕組みと どこで学ぶことができるかを説明します

    ではまず Swiftがサーバアプリに適している理由から 始めましょう

    Swiftは ガベージコレクションの代わりに 自動参照カウントを行うため C言語と同等のパフォーマンスが得られ メモリ消費も低減されます そのため 予測可能なリソース消費量と 高速な起動時間が求められる 最新のクラウドサービスに 最適です

    Swiftは表現力と安全性に優れた言語であり コンパイル時に様々なバグを排除するため デベロッパは 堅牢で信頼性の高い 分散システムを記述できます 強力な型付けやオプショナル メモリの安全性といった機能により Swiftサービスでは クラッシュやセキュリティの脆弱性が 生じにくくなっています

    クラウドサービスでは 高度な並列の ワークロード処理が多く生じます デベロッパは Swiftの 優れた並列処理機能により 拡張性と応答性に優れた サーバアプリを記述しつつ データ競合が原因の 一般的なバグの発生源を排除できます

    このような特性を備えたSwiftは サーバアプリ記述の優れた選択肢です Swiftは実際 Appleのクラウドサービスの 重要機能の多くに使われています iCloudキーチェーン 写真 メモなどです ほかの使用例としては App Storeの処理パイプライン SharePlayでのファイル共有があります 最新のプライベートクラウド コンピューティングサービスも Swift on Serverで構築されています

    Appleのサービス全体では Swift on Serverを 使用するアプリケーションが 毎秒数百万のリクエストを 処理しています

    Appleのプラットフォーム以外では Swiftを最も早期から使っていたのは サーバエコシステムです 実際 Swift Serverワークグループは Swiftのオープンソース化から わずか1年後の2016年に設立されました これは最も古いワークグループです

    ワークグループは Swift on Serverを 使用している企業を代表するメンバーと エコシステムの個人の貢献者で 構成されています サーバアプリの開発とデプロイにおける Swift利用の促進が主な活動目的です ワークグループの責務は サーバコミュニティの ニーズに対応するための 取り組みの定義と優先順位づけや 作業の重複の削減 互換性の向上 ベストプラクティスの促進のための パッケージのインキュベーションプロセスの 推進などです

    同グループはまた サーバエコシステムからのフィードバックを Swiftプロジェクトの 各グループに伝達します 次に サーバエコシステムの人気の パッケージを使って サービスを構築します 同僚と私は今年 多数のイベントに参加する予定です 計画を整理するために 誰がどのイベントに参加しているかを 追跡するイベントサービスを実装します サービスでは2つの操作をサポートします 1つは全イベントをリストし 誰がどのイベントに参加するか表示します オクトーバーフェストにも必ず行きたいので 新しいイベントを作成する もう1つの操作も必要です

    Swiftパッケージの作業では 各種エディタを使用できます XcodeやVS Code Neovimのほか 言語サーバプロトコルを サポートするその他のエディタも使えます このデモでは パッケージでの作業にVS Codeを使います デモでは 画面下の VS Codeの組み込みターミナルを使って サービスからの出力を確認し サービスにリクエストを送信します イベントサービスを開始するための パッケージは作成済みです 確認してみましょう

    パッケージはOpenAPI Generatorに依存し OpenAPIのサーバトランスポートとして Vaporを使います

    パッケージにはターゲットが2つあります

    1つはEventAPIターゲットで OpenAPIGeneratorプラグインが 構成されています

    もう1つは EventServiceの executableTargetで サービスの実装を含みます

    Swift OpenAPI Generatorにより サービスをYAMLで文書化し サーバ用と クライアント用のコードを生成できます OpenAPIを初めて使う方や 復習したい方は 昨年の 「Meet Swift OpenAPI Generator」を ぜひご覧ください OpenAPIのドキュメントを見てみましょう

    イベントパスで 両方の操作を定義しています

    最初の操作は listEventsというgetメソッドです

    この操作はイベントの配列を含む 成功レスポンスを返します

    2つ目の操作は createEventというpostメソッドです

    この操作は イベントのJSONの本文を受け取り

    作成が成功したかどうかに応じて 201または400のステータスコードを返します

    このサービスには メインエントリポイントが含まれます

    まずVaporアプリを作成します

    次に アプリケーションの OpenAPI VaporTransportを作成します

    次に サービスのインスタンスを作成し transportに登録します

    最後に Vaporアプリを実行します このアプリは HTTPサーバを起動し 外部からの接続をリッスンします

    このサービスはまた 生成されたAPIプロトコルを実装します

    listEventsメソッドは ハードコードされたイベントの配列を返します

    createEventメソッドは 現在 未実装のステータスコードを 返しています

    では サービスを起動しましょう

    これにより サービスがビルドされ デバッガがアタッチされます ターミナルの下部に サーバが起動したことが表示されます

    別のターミナルでcurlを使って サービスに照会し 全イベントを表示できるようになりました

    ハードコーディングされたイベントの リストを含む JSON配列が返されました

    しかし 新しいイベントを動的に追加し データベースで永続化させたいので データベースドライバを見てみます オープンソースのエコシステムには PostgreSQL MySQL Cassandra MongoDBなど 様々なデータベースドライバがあります

    今回は永続化のために Postgresデータベースを使用します PostgresNIOは VaporとAppleが保守する Postgres用の オープンソースデータベースドライバです PostgresClientは PostgresNIO 1.21の新機能です PostgresClientはまったく新しい 非同期のインターフェイスを提供し 構造化並列処理を活用する 接続プールが組み込まれているため データベースにおける 断続的なネットワーク障害に対する 耐性があります さらに 接続プールは スループットを向上させるために クエリを複数の接続に分散するとともに クエリ高速化のために 接続をウォームアップさせます

    PostgresNIOを使って データベースに EventServiceを接続しましょう

    最初に PostgresNIOへの依存関係を パッケージに追加し サービスにインポートします 次に PostgresClientを使用して listEventsメソッドで データベースへのクエリを行います 最後に createEventメソッドを実装して 新しいイベントをデータベースに挿入します まず パッケージマニフェストに PostgresNIOへの 依存関係を追加します

    次に EventServiceターゲットに 依存関係を追加します

    これで ServiceにPostgresNIOを サービスにインポートできます

    次に サービスに PostgresClientプロパティを追加します

    クライアントにより listEventsメソッドで データベースへのクエリを行います

    このクエリメソッドは 行のAsyncSequenceを返します ハードコードされたイベントのリストを 置換するために 行を反復処理し フィールドをデコードして 各行のイベントを作成します

    クエリメソッドから返された AsyncSequenceは データベースから自動的に 行を事前に取得して パフォーマンスを高速化します

    サービスを再実行する前に PostgresClientサービスを作成して サービスに渡す必要があります

    まず PostgresClientを作成し すでにローカルで起動している データベースに接続します

    次に PostgresClientをサービスに渡します

    クライアントを起動するために runメソッドを呼び出し 現在のタスクを 終了時点まで 引き継がせます VaporアプリとPostgresClientの両方を 同時に実行するために タスクグループを使います 破棄するタスクグループを作成し PostgresClientを実行する 子タスクを追加します

    次に Vaporアプリの実行を 別の子タスクに移します

    サービスを再実行しましょう

    再実行ボタンを押すと 現行のプロセスが停止し サービスが再ビルドされ 再実行されます

    ターミナル下部に実行中の表示が出ます 再度全イベントを表示しましょう

    データベースが空のようです 新しいイベントをデータベースに 追加するために createEventメソッドを実装します

    まず 入力を切り替えて JSONイベントを抽出する必要があります

    次に データベースへのクエリを実行し 新しいイベントを挿入します

    最後に イベントを作成したという 内容を返します

    このコードを見て一部の人には警告がなるかもしれません ほかの言語では SQLインジェクション脆弱性の 一般的な攻撃経路だからです 文字列のように見えますが これは文字列ではなく Swiftの文字列補間機能を使用して 文字列クエリを 値がバインドされた パラメータ化クエリに変換しているので SQLインジェクション攻撃から 完全に保護されます コードの安全性を確保しつつ 使いやすさを追求する Swiftの取り組みの好例と言えます

    サービスを再実行しましょう

    サービスが再開したら curlを使って2つのイベントを作成します

    イベント作成は成功したようです 全イベントを再び表示し データベースに保存されているか 確認してみましょう

    すべてのイベントが データベースに保存されています Gusがメッセージで 友達を連れてきたいと言い 彼の名前で別のイベントエントリを 追加するよう頼んでいます Gusのために イベントをもう1つ作成しましょう

    Gusの名前で 別のイベントエントリを追加する際 問題が生じたようです ターミナルの下部に 長いエラーメッセージがありますが このエラーからは 問題を正確に把握できません 既知の情報は 処理が未完了であることと スローされたエラーの型が PSQLErrorであることだけです PSQLErrorの説明では 意図的に詳細情報を省略します テーブルのスキーマなどの データベース情報の漏洩を 防ぐためです このような場合に トラブルシューティングに役立つのが サービスへの オブザーバビリティの追加です オブザーバビリティの3つの主な要素は ログ メトリックス トレースです ログにより サービスの実行内容を正確に把握して 問題のトラブルシューティングを行いつつ 詳細を調査できます メトリックスを利用すれば 迅速に サービスの健全性の概要を把握できます ログとメトリックスは 単一のサービスの状況の把握に有効ですが 現代のクラウドシステムは多くの場合 分散システムの集合体です トレースはこうしたシステムで役立ちます リクエストが辿った システム内の経路がわかるためです

    以上3つの要素をすべて網羅した SwiftエコシステムのAPIパッケージでは オブザーバビリティイベントを コードで出力できます

    listEventsメソッドを インスツルメントする方法を確認しましょう

    まず swift-logを使い 新しいlistEventsリクエストの処理の 開始時のログを出力します swift-logは ログメッセージに メタデータを追加して構造化ログを提供し トラブルシューティングのための コンテキストを追加します

    次に swift-metricsの カウンターを追加します これをリクエストごとに増加させ サービスが処理したリクエスト数を追跡します

    最後に swift-distributed-tracingを追加し データベースクエリの前後に スパンを作成します これは システム全体でのリクエストの トラブルシューティング用です Swiftの分散トレースの仕組みの 詳細については 昨年のセッションをご覧ください 「Beyond the basics of structured concurrency」です listEventsメソッドを ログ メトリックス トレースで インスツルメントしました 使用したAPIは オブザーバビリティの バックエンドに非依存で データの送信先は サービスの作成者が選択します ログ メトリックス 分散トレースのための 多数のバックエンドを Swift on Serverエコシステムは 提供しています バックエンドの選択は 3つのライブラリの ブートストラップメソッドを 呼び出すことで実行します ブートストラップは 実行可能ファイル内でのみ実行され オブザーバビリティイベントの保持のため 可能な限り早期に実行する必要があります またブートストラップの実行順は 最初にLoggingSystem 次にMetricsSystem 最後にInstrumentationSystemが 推奨されます メトリックスと インスツルメンテーションのシステムが ステータスログを 出力することがあるためです

    わずか2行のコードで ログをターミナルに メトリックスをPrometheusに トレースをOpen Telemetryに出力できました createEventメソッドにログ作成を追加して Gusの名前で別のイベントを 追加しようとした時 何が問題だったのか確認しましょう

    まずswift-logを パッケージと EventServiceターゲットの依存関係として 追加します

    次に サービスに Loggingモジュールをインポートします

    次に クエリメソッドがスローした エラーを捕捉します

    クエリメソッドはクエリ実行時に 何らかの問題が発生した場合 PSQLErrorをスローします

    Postgresサーバが送信した エラーメッセージを含む ログイベントを出力できるよう ロガーを作成しましょう

    次に エラーメッセージを抽出し ログを出力します PSQLErrorでは 問題の原因の詳細情報が serverInfoプロパティに 含まれています

    最後に データベースへのイベント追加時に 問題が発生したことを示すために badRequestレスポンスを返します

    サービスを再実行して エラーの詳細を取得できるか 確認しましょう

    デフォルトでは swift-logはターミナルにログを 出力しますが これはアプリのデバッグに最適です 同じcurlコマンドを実行し イベントを再作成します

    今回は同じエラーが発生しませんでした badRequestステータスコードを 返したためです

    サービスのログをチェックして 問題を確認しましょう

    ターミナルの下部に ログメッセージが表示されています エラーメッセージの メタデータフィールドによると 原因は重複キー違反です このデータベースのテーブルで 許可されるエントリは 名前 日付 出席者の組み合わせに対し 1つのみです

    ログの追加が 具体的な問題の解決に役立ちました あとで同僚に修正してもらいます

    サービスの構築に使用できる Swift on Serverエコシステムのライブラリを 手短にご紹介しました 様々な用途向けのライブラリが ほかにも多数あります 例えば ネットワーキング データベースドライバ オブザーバビリティ メッセージストリーミングなど これらはほんの一部です ほかのライブラリを探したい場合 swift.orgのPackagesセクションの Serverのカテゴリをご確認ください swiftのPackagesのインデックスから ほかのサーバライブラリも探せます

    パッケージ検索のもう1つのリソースは Swift Serverワークグループの インキュベーションリストです ワークグループは パッケージの育成プロセスを推進し 安定した強固なエコシステムを築いています

    育成プロセスにあるパッケージは SandboxからIncubatingへ そしてGraduatedへと 成熟度に応じて移行します

    各レベルの要件は パッケージの 本番リリースに向けた準備状況と 使用状況に基づきます 育成されたパッケージは swift.orgで確認できます

    Swift on Serverのエコシステムの セッションはいかがでしたか Swiftがサーバアプリに 適した言語である理由と Appleのクラウドサービスの重要機能の 多くでの利用状況を説明しました パッケージの概要と Swift Serverワークグループの 健全なエコシステムの構築への貢献を ご紹介しました ご視聴ありがとうございました オクトーバーフェストで会いましょう

    • 3:23 - EventService Package.swift

      // swift-tools-version:5.9
      import PackageDescription
      
      let package = Package(
        name: "EventService",
        platforms: [.macOS(.v14)],
        dependencies: [
          .package(
            url: "https://github.com/apple/swift-openapi-generator",
            from: "1.2.1"
          ),
          .package(
            url: "https://github.com/apple/swift-openapi-runtime",
            from: "1.4.0"
          ),
          .package(
            url: "https://github.com/vapor/vapor",
            from: "4.99.2"
          ),
          .package(
            url: "https://github.com/swift-server/swift-openapi-vapor",
            from: "1.0.1"
          ),
        ],
        targets: [
          .target(
            name: "EventAPI",
            dependencies: [
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
            ],
            plugins: [
              .plugin(
                name: "OpenAPIGenerator",
                package: "swift-openapi-generator"
              )
            ]
          ),
          .executableTarget(
            name: "EventService",
            dependencies: [
              "EventAPI",
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
              .product(
                name: "OpenAPIVapor",
                package: "swift-openapi-vapor"
              ),
              .product(
                name: "Vapor",
                package: "vapor"
              ),
            ]
          ),
        ]
      )
    • 4:05 - EventService openapi.yaml

      openapi: "3.1.0"
      info:
        title: "EventService"
        version: "1.0.0"
      servers:
        - url: "https://localhost:8080/api"
          description: "Example service deployment."
      paths:
        /events:
          get:
            operationId: "listEvents"
            responses:
              "200":
                description: "A success response with all events."
                content:
                  application/json:
                    schema:
                      type: "array"
                      items:
                        $ref: "#/components/schemas/Event"
          post:
            operationId: "createEvent"
            requestBody:
              description: "The event to create."
              required: true
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/Event'
            responses:
              '201':
                description: "A success indicating the event was created."
              '400':
                description: "A failure indicating the event wasn't created."
      components:
        schemas:
          Event:
            type: "object"
            description: "An event."
            properties:
              name:
                type: "string"
                description: "The event's name."
              date:
                type: "string"
                format: "date"
                description: "The day of the event."
              attendee:
                type: "string"
                description: "The name of the person attending the event."
            required:
              - "name"
              - "date"
              - "attendee"
    • 4:35 - EventService initial implementation

      import OpenAPIRuntime
      import OpenAPIVapor
      import Vapor
      import EventAPI
      
      @main
      struct Service {
        static func main() async throws {
          let application = try await Vapor.Application.make()
          let transport = VaporTransport(routesBuilder: application)
      
          let service = Service()
          try service.registerHandlers(
            on: transport,
            serverURL: URL(string: "/api")!
          )
      
          try await application.execute()
        }
      }
      
      extension Service: APIProtocol {
        func listEvents(
          _ input: Operations.listEvents.Input
        ) async throws -> Operations.listEvents.Output {
          let events: [Components.Schemas.Event] = [
            .init(name: "Server-Side Swift Conference", date: "26.09.2024", attendee: "Gus"),
            .init(name: "Oktoberfest", date: "21.09.2024", attendee: "Werner"),
          ]
      
          return .ok(.init(body: .json(events)))
        }
      
        func createEvent(
          _ input: Operations.createEvent.Input
        ) async throws -> Operations.createEvent.Output {
          return .undocumented(statusCode: 501, .init())
        }
      }
    • 6:56 - EventService Package.swift

      // swift-tools-version:5.9
      import PackageDescription
      
      let package = Package(
        name: "EventService",
        platforms: [.macOS(.v14)],
        dependencies: [
          .package(
            url: "https://github.com/apple/swift-openapi-generator",
            from: "1.2.1"
          ),
          .package(
            url: "https://github.com/apple/swift-openapi-runtime",
            from: "1.4.0"
          ),
          .package(
            url: "https://github.com/vapor/vapor",
            from: "4.99.2"
          ),
          .package(
            url: "https://github.com/swift-server/swift-openapi-vapor",
            from: "1.0.1"
          ),
          .package(
            url: "https://github.com/vapor/postgres-nio",
            from: "1.19.1"
          ),
        ],
        targets: [
          .target(
            name: "EventAPI",
            dependencies: [
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
            ],
            plugins: [
              .plugin(
                name: "OpenAPIGenerator",
                package: "swift-openapi-generator"
              )
            ]
          ),
          .executableTarget(
            name: "EventService",
            dependencies: [
              "EventAPI",
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
              .product(
                name: "OpenAPIVapor",
                package: "swift-openapi-vapor"
              ),
              .product(
                name: "Vapor",
                package: "vapor"
              ),
              .product(
                  name: "PostgresNIO",
                package: "postgres-nio"
              ),
            ]
          ),
        ]
      )
    • 7:08 - Implementing the listEvents method

      import OpenAPIRuntime
      import OpenAPIVapor
      import Vapor
      import EventAPI
      import PostgresNIO
      
      @main
      struct Service {
        let postgresClient: PostgresClient
        
        static func main() async throws {
          let application = try await Vapor.Application.make()
          let transport = VaporTransport(routesBuilder: application)
      
          let postgresClient = PostgresClient(
            configuration: .init(
              host: "localhost",
              username: "postgres",
              password: nil,
              database: nil,
              tls: .disable
            )
          )
          let service = Service(postgresClient: postgresClient)
          try service.registerHandlers(
            on: transport,
            serverURL: URL(string: "/api")!
          )
      
          try await withThrowingDiscardingTaskGroup { group in
            group.addTask {
              await postgresClient.run()
            }
      
            group.addTask {
              try await application.execute()
            }
          }
        }
      }
      
      extension Service: APIProtocol {
        func listEvents(
          _ input: Operations.listEvents.Input
        ) async throws -> Operations.listEvents.Output {
          let rows = try await self.postgresClient.query("SELECT name, date, attendee FROM events")
      
          var events = [Components.Schemas.Event]()
          for try await (name, date, attendee) in rows.decode((String, String, String).self) {
            events.append(.init(name: name, date: date, attendee: attendee))
          }
      
          return .ok(.init(body: .json(events)))
        }
      
        func createEvent(
          _ input: Operations.createEvent.Input
        ) async throws -> Operations.createEvent.Output {
          return .undocumented(statusCode: 501, .init())
        }
      }
    • 9:02 - Implementing the createEvent method

      func createEvent(
        _ input: Operations.createEvent.Input
      ) async throws -> Operations.createEvent.Output {
        switch input.body {
        case .json(let event):
          try await self.postgresClient.query(
            """
            INSERT INTO events (name, date, attendee)
            VALUES (\(event.name), \(event.date), \(event.attendee))
            """
          )
          return .created(.init())
        }
      }
    • 11:34 - Instrumenting the listEvents method

      func listEvents(
        _ input: Operations.listEvents.Input
      ) async throws -> Operations.listEvents.Output {
        let logger = Logger(label: "ListEvents")
        logger.info("Handling request", metadata: ["operation": "\(Operations.listEvents.id)"])
      
        Counter(label: "list.events.counter").increment()
      
        return try await withSpan("database query") { span in
          let rows = try await postgresClient.query("SELECT name, date, attendee FROM events")
          return try await .ok(.init(body: .json(decodeEvents(rows))))
        }
      }
    • 13:14 - EventService Package.swift

      // swift-tools-version:5.9
      import PackageDescription
      
      let package = Package(
        name: "EventService",
        platforms: [.macOS(.v14)],
        dependencies: [
          .package(
            url: "https://github.com/apple/swift-openapi-generator",
            from: "1.2.1"
          ),
          .package(
            url: "https://github.com/apple/swift-openapi-runtime",
            from: "1.4.0"
          ),
          .package(
            url: "https://github.com/vapor/vapor",
            from: "4.99.2"
          ),
          .package(
            url: "https://github.com/swift-server/swift-openapi-vapor",
            from: "1.0.1"
          ),
          .package(
            url: "https://github.com/vapor/postgres-nio",
            from: "1.19.1"
          ),
          .package(
              url: "https://github.com/apple/swift-log",
              from: "1.5.4"
          ),
        ],
        targets: [
          .target(
            name: "EventAPI",
            dependencies: [
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
            ],
            plugins: [
              .plugin(
                name: "OpenAPIGenerator",
                package: "swift-openapi-generator"
              )
            ]
          ),
          .executableTarget(
            name: "EventService",
            dependencies: [
              "EventAPI",
              .product(
                name: "OpenAPIRuntime",
                package: "swift-openapi-runtime"
              ),
              .product(
                name: "OpenAPIVapor",
                package: "swift-openapi-vapor"
              ),
              .product(
                name: "Vapor",
                package: "vapor"
              ),
              .product(
                  name: "PostgresNIO",
                package: "postgres-nio"
              ),
              .product(
                  name: "Logging",
                  package: "swift-log"
              ),
            ]
          ),
        ]
      )
    • 13:38 - Adding logging to the createEvent method

      func createEvent(
        _ input: Operations.createEvent.Input
      ) async throws -> Operations.createEvent.Output {
        switch input.body {
        case .json(let event):
          do {
            try await self.postgresClient.query(
              """
              INSERT INTO events (name, date, attendee)
              VALUES (\(event.name), \(event.date), \(event.attendee))
              """
            )
            return .created(.init())
          } catch let error as PSQLError {
            let logger = Logger(label: "CreateEvent")
      
            if let message = error.serverInfo?[.message] {
              logger.info(
                "Failed to create event",
                metadata: ["error.message": "\(message)"]
              )
            }
            
            return .badRequest(.init())
          }
        }
      }
  • 特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。

    クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。

Developer Footer

  • ビデオ
  • WWDC24
  • サーバエコシステムでのSwiftの詳細
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン