忙しい人向けの Use Swift on AWS Lambda with Xcode - #WWDC20
サーバレスとSwift
Server コンポーネントは Client の機能を拡張することができ、デバイス上では行えない作業や重い処理を扱うことができる。
サーバレス機能はイベントドリブンで動作する。スケールしやすくコストコントロールもしやすい。AWS Lambda はこの分野のリーダー的な存在。
サーバレス機能は、コストに直接影響するコンピューティングリソースに注意を払う必要がある。Swift は『開発者の利便性』と『低リソース』を同時に実現しており、サーバレス機能に向いている。
Swift on AWS Lambda
このようにたった4行で記述できる。イベントペイロードが処理できるようになるとクロージャが呼び出され、ランタイムライブラリが AWS Lambda のプラットフォームと相互作用を管理する。
より繊細なパフォーマンスが必要な場合のために、SwiftNIO を活用した Protocol ベースの API も提供している。これはネットワーク処理スタックと同スレッドで動作するためコンテキストスイッチを防げる。しかし、イベントループをブロックしないように注意する必要があり、複雑になる。
ほとんどの場合はクロージャベースの API が適している。この例ではリクエスト・レスポンスの構造体を Codable に準拠し、JSON のシリアライズ・デシリアライズをかんたんに実現している。
Xcode で開発するデモ
Xcode で開発する方法を見ていく。このワークスペースには iOS / Lambda の2つのプロジェクトが含まれており、Lambda プロジェクトは Swift AWS Lambda Runtime に依存している。
エントリポイントは次のようになる。ここではリクエスト・レスポンス用に2つの構造体も定義している。
iOSアプリ側は SwiftUI で作成されており、『名前』と『パスワード』を入力してボタンをタップすると、リクエスト用のメソッドを呼び出すようになっている。
register メソッドと Lambda の実装はどうやって結びつくのだろう?
試しに Lambda プロジェクトを実行してみると、コンソールにエラーが出力される。これは実際の AWS Lambda 上ではなく、Xcode 上で動作させているためだ。
幸い、ランタイムライブラリには AWS Lambda のランタイムエンジンをシミュレーションするモードが備わっており、環境変数 LOCAL_LAMBDA_SERVER_ENABLED = true で有効にできる。
この状態で実行すると、ローカルの7000番ポートをリッスンし、/invoke エンドポイントでイベントを待ち受けているのが分かる。
先程の register メソッドの実装は次のようになる。通常の URLSession を利用して http://127.0.0.1:7000/invoke にリクエストしている。動作確認のため、このメソッド内と Lambda 関数内にブレークポイントを設定しておく。
iOSアプリを起動すると、Xcode は2つのプロセスを管理しているのが分かる。また、Lambda 側はわずか 6.3MB で動作していることも分かる。
シミュレータで『名前』と『パスワード』を入力して、登録ボタンをタップすると・・・
最初のブレークポイントに止まる。処理を継続すると・・・
今度は Lambda 関数側のブレークポイントに止まる。LLDB でリクエストの中身を確認すると、入力した値が入っている。さらに続けると・・・
request メソッド側のレスポンス処理の部分で止まる。続けると・・・
アプリ側にレスポンスの結果が表示された。
仕組みはこう。環境変数でローカルデバッグモードを指定することで、ローカルに HTTP サーバを立ち上げ、AWS Lambda ランタイムエンジンをシミュレートすることで、iOSアプリからの HTTP リクエストを処理する。
AWS へのデプロイ
実際に AWS にデプロイするには AWS CLI などのツールを利用する必要がある。ここではそれをラップした簡易なスクリプトで実行する例をみる。
流れは次のようになる。
1. Amazon Linux2イメージをベースにした Docker イメージをビルド。
2. Dockerコンテナ内で、作成した Lambda 関数をコンパイル。
3. 実行ファイルと依存リソースを zip でアーカイブ。
4. zip を AWS にアップロードして、最新のコードとして更新。
仕組みはこう。AWS API Gateway が HTTP リクエストを待ち受け、イベントがキューに格納されたら Lambda Runtime Engine がそれを取得し、HTTP コールとして Lambda 関数を呼び出す。
我々がやった2つのこと
これらを実現するために私達は大きく2つのことをした。1つ目は、Amazon Linux 2 イメージ向けの Swift ツールチェーンを公開した。
2つ目は、Swift 向けの AWS Lambda Runtime ライブラリの公開。
ライブラリは多階層の API で構成されており、AWS Lambda 上で効率的に動作するように様々な注意が払われている。例えば、プロセスが長寿命の場合にはネットワークコネクションをキャッシュしたりなど。
AWS プラットフォームとの統合も用意されており、S3 などの他サービスや、カスタムイベントにも対応できる。
まとめ
Swift は高速・安全・低リソースだからサーバレスに向いている。今日からつくれる状態だから是非試してみてね。
免責
・本記事は公開情報のみに基づいて作成されています。
・要約(意訳)のみなので、詳細はセッション動画をご確認ください。
役に立った記事などありましたらサポート頂けると嬉しいです。