IBM Cloud Functions を Swift で使う【実践編】
以前、IBM Cloud Functions の Hello World を Swift でやってみました.
今回は IBM Cloud Functions をより実践的な観点で使ってみました.
実装環境
- macOS High Sierra 10.13.2
- Docker for Mac 17.12.0
- Xcode 9.4
- Swift 4.1
パッケージ導入
実戦的に使う上でまず気になるのはパッケージの導入でしょうか.
大丈夫です、Functions でも外部パッケージを導入できます.
GitHub に外部パッケージを含めるビルド手順が記載されています.
必要なのは以下の手順です.
- ビルドスクリプト(compile.sh) を作成する(コピペでOK)
- 利用パッケージ一覧(Package.swift) を作成する
- メイン関数(main.swift) を作成する
- ビルドする
ディレクトリ構成は以下のようになります.
今回は NoSQL DB である Cloudant の Swift SDK を使ってみたいと思います.
対応する Package.swift は以下のようになります.
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "Action",
products: [
.executable(
name: "Action",
targets: ["Action"]
)
],
dependencies: [
.package(url: "https://github.com/cloudant/swift-cloudant.git", .upToNextMajor(from: "0.8.0"))
],
targets: [
.target(
name: "Action",
dependencies: ["SwiftCloudant"],
path: "."
)
]
)
メイン関数
Functions の実際の処理となるメイン関数です.
import Foundation
import SwiftCloudant
func main(args: [String:Any]) -> [String:Any] {
// Create a CouchDBClient
let cloudantURL = URL(string:"https://XXXX-bluemix.cloudant.com")!
let client = CouchDBClient(url:cloudantURL, username:"XXXX-bluemix", password:"XXXXd8d8816d7a7ca")
let dbName = "transaction"
var _error : Error?
var _response : [String : Any]?
// Read a document
let read = GetDocumentOperation(id: "XXXX", databaseName: dbName) { (response, httpInfo, error) in
if let error = error {
_error = error
} else {
_response = response
}
}
client.add(operation:read)
// Wait for Cloudant's response
while true {
usleep(100)
if (_error != nil || _response != nil) {
break
}
}
// Return response
if _response != nil {
print("response ... \(_response)")
return _response!
} else {
print("error ... \(_error)")
return (["error":"\(_error)"])
}
}
JSON を返す Action になるので返り値は [String:Any] になります.
また、print(“…”) は Logs として JSON 形式で Functions 上に出力されます.
[
“2018-06-17T04:58:16.361178453Z stdout: response … Optional([\”_rev\”: \”1-XXXX\”, \”pageId\”: 21, \”_id\”: \”XXXX\”, \”dateTimeLocal\”: \”2017-10-22T01:48:42.849+09:00[Asia/Tokyo]\”, \”pageName\”: \”MF-Overview\”])”,
“2018-06-17T04:58:16.361148831Z stderr: 2018-06-17 04:58:16.155 Action[11:2ae60700] Cookie request successful”
]
ビルド&デプロイ
ソースコードが用意できましたらいよいよビルド&デプロイです.
まずはソースコードをビルドします.
compile.sh を実行します.
第一引数にソースコードが配置されているディレクトリ名を、第二引数に Swift のバージョンを設定します.
以下、実行結果です.
functions $ bash compile.sh hello swift:4.1
+ ‘[‘ -z hello ‘]’
+ ‘[‘ -z swift:4.1 ‘]’
+ OUTPUT_DIR=build
+ ‘[‘ swift:4.1 == swift:3.1.1 ‘]’
+ ‘[‘ swift:4.1 == swift:4.1 ‘]’
+ RUNTIME=openwhisk/action-swift-v4.1
+ BASE_PATH=/swift4Action
+ DEST_SOURCE=//swift4Action/spm-build/Sources/Action
+ DEST_PACKAGE_SWIFT=/swift4Action/spm-build/Package.swift
+ BUILD_FLAGS=
+ ‘[‘ -n ” ‘]’
+ echo ‘Using runtime openwhisk/action-swift-v4.1 to compile swift’
Using runtime openwhisk/action-swift-v4.1 to compile swift
++ pwd
+ docker run –rm –name=compile-ow-swift -it -v /Users/DaikiKawanuma/Desktop/functions:/owexec openwhisk/action-swift-v4.1 bash -ex -c ‘…
Linking ./.build/x86_64-unknown-linux/release/Action
+ echo ‘Creating archive hello.zip…’
Creating archive hello.zip…
+ mkdir -p /owexec/build
+ zip /owexec/build/hello.zip .build/release/Action
adding: .build/release/Action (deflated 73%)
次にデプロイです.
Blumix CLI をインストールし、Cloud Functions プラグインを導入します.
以下の手順をご参照ください.
デプロイコマンドを実行します.
functions $ bx wsk action update helloworld build/hello.zip –kind swift:4.1
ok: updated action helloworld
これで作成手順は完了です.
実装結果
Functions のダッシュボート上で Invoke してみます.
実行結果です.
DB アクセス込みで 1,000ms 程度であればまずまずではないでしょうか.
まとめ
今回は IBM Cloud Functions を Swift で、より実践的な観点で使ってみました.
以下の点は実運用上で利点になるかと思います.
- 外部のパッケージを利用できる
- パッケージをコードで管理できる(Package.swift)
- ビルド・デプロイがコマンドで実行できるため CI/CD に組み込める
Swift を使える Functions はあまり無いと思うのでぜひ使ってみていただければと思います.
Enjoy サーバーサイド Swift!(サーバーレスだけど)
以上です.
PS. 情報提供いただいた @taiponrock さんありがとうございましたorz