Help us understand the problem. What is going on with this article?

サーバーレスサーバーサイドSwiftとHexaville

More than 3 years have passed since last update.

はじめに

こんにちは、tk1024です。
この前の金曜日にTokyo Server Side Swift Meetup #7が行われました。

その中でYuki Takei (noppoMan)さんがServer Less Server Side Swift with Hexavilleという物を発表していたので今回も関連するMediumの記事を翻訳してみました。
元記事: Serverless Server Side Swift with Hexaville

Google翻訳に毛が生えた程度なので誤字脱字・翻訳間違い等、コメントでも編集リクエストでも送っていただければ幸いです。

以下、翻訳


サーバーレスサーバーサイドSwiftとHexaville

Hello World.

自分で起こした会社でSwiftを使いサーバーサイド、クライアントサイドアプリケーションを書いています。この会社は自己資金を使い2人だけ(自分とco-founder/Engineer)で運営しています。充分な資金が無く潤沢なサーバーインスタンスも24時間サーバー立ち上げ続ける為に人を雇う余裕もありません。

ベンチャー企業をはじめるに当たり、このような状況でサーバーレスコンピューティングは1つの解決法だと期待しています。

サーバーレスコンピューティング

function as a service (FaaS)として知られているサーバーレスコンピューティングはクラウド事業者がplatform as a service (PaaS)コンテナ内でリクエストに応じてコードを実行するモデルです。
また仮想マシン毎ではなくリクエスト処理の実行時間で課金されるのでリソースにかかる支払額をより抽象的に測ることができます。

サーバーレスコンピューティングではコードが実行された場合のみ料金が発生します。(かなり安い)
これにより、サーバーインスタンスにかかる費用を気にする必要がなくなります。
そして多くの場合、クラウド事業者がサービスをフルマネージするので、スケーリングについて気にする必要もありません。

完璧に見えますが欠点もあります。
- クラウド事業者に縛られる
- クラウドサービスを使えなければならない
- クラウドサービスがダウンするとサービスもダウンする
- デプロイとルーティングを管理画面から操作する必要がある(Not programmatically)
- ミドルウェアとのコネクションを維持できない
- 同時並列実行にリミットがある(上限引き上げには申請が必要)

HexavilleはサーバーレスなSwift webアプリケーションを作るために作りました。同時に上に書いたいくつかの欠点も克服しています。

Hexaville

Github: noppoMan/Hexaville

Swiftの為のモダンなWebアプリケーションフレームワーク及びエンジン

Swiftで作られたwebアプリをlambdaとapi-gatewayで実行する事をコンセプトにしています。

これらは、Swiftのビルドとデプロイ、実際にlambdaのHexavilleフレームワーク上で実行するアプリケーション作る2つのレイヤーに分かれています。

Hexavilleを使いサーバーレスアプリケーションの作成とクラウド上へのデプロイをする

これからHexavilleを使ってサーバーレスアプリケーションを実際にビルドしていきます。
インストールはすごく簡単です。クローンしてビルドする、それだけです。

以下に書くコマンドは全てMacで実行したものです。(El Capitan, Xcode 8.3.2)

インストール

git clone https://github.com/noppoMan/Hexaville.git
cd Hexaville
swift build

Hexavilleプロジェクトを生成する

まず、オプションなしでHexavilleを実行します。

./.build/debug/Hexaville

出力はこのようになります。

Available commands:

- generate            Generate initial project

- deploy              Deploy your application to the specified cloud provider

- routes              Show routes and endpoint for the API

- help                Prints this help information

- version             Prints the current version of this app

実行可能なコマンド(Available commands)を見てください。
そして、generateコマンドを実行して最初のHexavilleプロジェクトを初期化してください。

./.build/debug/Hexaville generate --dest /Users/name/Desktop/Hello

generateコマンド実行後にはHelloディレクトリが作られていると思います。中を覗いてみましょう!

/Users/name/Desktop
├── Hexavillefile.yml
├── Package.swift
└── Sources
    ├── RandomNumberGenerateMiddleware.swift
    └── main.swift

1 directory, 4 files

ディレクトリは一般的なSwift Package Managerプロジェクトの構成です。swift package generate-xcodeprojを実行する事で自動でxcodeprojを生成する事ができます。これはXcodeでHexavilleアプリケーションを開発できる事を意味します。

cd ~/Desktop/Hello
swift package generate-xcodeproj
open *.xcodeproj

このようにしてXcodeで開く事ができます。

main.swift


main.swiftの中にはHexavilleフレームワークのサンプルコードが書かれています。ExpressやSinatraと似ています。

編集しないでデプロイしてみます。

Edit Hexavillefile.yml

Hexavillefile.ymlはHexavilleの設定ファイルです。

設定ファイルを開いて、credential, region, lambdaのroleを埋めてください。
(credential, region, passは環境変数として省略する事もできます)

name: test-app
service: aws
aws:
  credential:
    access_key_id: xxxxxxxxxxxxx
    secret_access_key: xxxxxxxxxxxxx
  region: us-east-1
  lambda:
    role: arn:aws:iam::xxxxx:role/xxxxxxxxxxxxx
    timout: 10
build:
  nocache: false

Deploy

では、deployコマンドでデプロイしましょう

/path/to/your/Hexaville/.build/debug/Hexaville deploy Hello

時間がかかるのでしばらく待ちます...

ルーティング情報を取得する

次に、デプロイしたリソースを確認するためにルーティングを取得してみましょう。

/path/to/your/Hexaville/.build/debug/Hexaville routes

このように出力されます

Endpoint: https://{id}.execute-api.{region}/staging
Routes:
  GET    /hello
  GET    /random_img
  GET    /
  POST   /hello/{id}
  GET    /hello/{id}

リソースにアクセス

curlでリソースのエンドポイントにアクセスします

curl https://{id}.execute-api.{region}/staging/

<html><head><title>Hexaville</title></head><body>Welcome to Hexaville!</body></html>

もしHTMLファイルをエンドポイントから取得できていれば、デプロイは成功です。

やったね!

デプロイフローの詳細

実際にlambda上での動作を確認しましたが、lambdaは現在Swiftのランタイムをサポートしていません。では、どのようにしてlambda上でSwiftを実行してのか説明していきます。

はじめにデプロイフローの図をご覧ください。この図に従って何をしているのか説明していきます。

Build Swift on Dockerを見てください。
もし、SwiftをMac上でビルドしてバイナリをアップロードするとAmazon Linux上で実行するlambdaでは動きません。

なので、Linux_x86と互換性のあるバイナリをビルドするためにDocker for Macを使う必要があります。

そして、ビルドされたバイナリと関連するオブジェクトは-vオプションでdockerとホストマシンの共有ディレクトリにデプロイされます。

また、Linux上でSwiftのバイナリを実行するには以下の.soファイルが必要です。

/${SWIFTFILE}/usr/lib/swift/linux/*.so
/usr/lib/x86_64-linux-gnu/libicudata.so
/usr/lib/x86_64-linux-gnu/libicui18n.so
/usr/lib/x86_64-linux-gnu/libicuuc.so
/usr/lib/x86_64-linux-gnu/libbsd.so

これらをディレクトリにまとめて、zipファイルにした後にAWS S3にアップロードします。

また、Hexavilleアプリケーションのルーティングがapi-gatewayにそのまま反映されている事を不思議だと思いましたか?

Hexavilleフレームワークで作られたアプリケーションはコマンドラインアプリケーションとして実行できます。

Available commands:
- gen-routing-manif   Generate routing manifest file
- execute             Execute the specified resource. ex. execute GET /
- serve               Start Hexaville Builtin Server
- help                Prints this help information
- version             Prints the current version of this app

gen-routing-manifコマンドに注目してください。

このコマンドを一度、実行してみてください。
Hexavilleフレームワークアプリケーションからルーティング情報を抽出して.routing-manifest.jsonに出力します。

.routing-manifest.json
{
  "routing" : [
    {
      "method" : "get",
      "path" : "\/"
    },
    {
      "method" : "get",
      "path" : "\/hello"
    },
    {
      "method" : "get",
      "path" : "\/hello\/{id}"
    },
    {
      "method" : "post",
      "path" : "\/hello\/{id}"
    },
    {
      "method" : "get",
      "path" : "\/random_img"
    }
  ]
}

.routing-manifest.json はapi-gatewayのRestAPIのパラメータをマップしたものです。

Lambda上でどのようにしてSwiftを実行するのか

最後に、lambda上でどのようにしてSwiftのバイナリを実行するのか説明します。

この図が示すようにNode.jsをlambdaのランタイムとして、Swiftバイナリをchild_processモジュールでプロセスとして生成しています。

生成後、オリジンプロトコルで子プロセスから親プロセスにパイプでメッセージを送っています。

追伸

どうでしたか?

Hexavilleはまだ幾つかの機能しかなくできることは多くありませんが、実際に動かしながらフィードバックを提供し続けていきたいと思います。

次は以下の機能を実装しようと考えています。
- ログ出力(Cloud watch logs -> Amazon Athena)
- VPCサポート
- カスタムドメインサポート
- バイナリメディアサポート

これらの機能があれば、実用的なWebアプリケーションを作成する選択肢の1つになると私は信じています。

訳者あとがき

Github: noppoMan/Hexaville
Twitter: @noppoMan722
Connpass: Tokyo Server Side Swift Meetup

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした