›サーバーサイドをNodeからSwiftに移行するツイート読了時間20分こんにちは。リードアーキテクトのItoです。最近アナログオーディオをやっているのですが、つらい事件が起きました。今月はじめにSwiftのコンパイラなどのソースコードがGithubで公開され、かなりの反響を呼びました。コンパイラだけではなく、パッケージマネージャやコアライブラリ、今後のマイルストーン、コーディング規約など、Swiftが一つのエコシステムとして公開されたことで、さらに盛り上がりを見せている気がします。Swiftという世界的なカンファレンスが渋谷・東京で行われるので、面白い四半期になりそうです。私もチケットを購入したので行く予定です。カメリオは、iOS版がSwift、バックエンドのサーバーがNode.jsとPythonで書かれています。サーバーのAPIは、フロントAPIとバックエンドAPIに分かれ、マイクロサービス化がなされています。iOSのSwift化の話についてはこちら、マイクロサービスの構成についての話はこちらをご覧ください。今回はサービス全体をSwiftに移行しようという話なのですが、フロントAPIサービスを移行する場合について考えてみます。フロントAPIは、Node.js(Express)で書かれたAPIサーバーで、仕事は、主にiOS版、Android版、Web版のAPIリクエストを受け付けます。セッションを管理したり、ユーザーの情報(フォローしているテーマ一覧・クリップ機能・広告・課金)などを処理するAPIを提供します。記事や分類に関する処理はバックエンドのPythonベースのサーバーが主です。Nodeは最近v4系にアップデートされ、ES6の一部機能や、Promise、Generators(yield)などが使えるようになって、コールバックを意識せずに非同期処理を簡潔に書けるようになりました。最近新しく書いた部分に関しては新しい機能が使えてよいです。[req.user.user_id])※yieldで非同期処理(SQLクエリの実行)を行う従来のコールバックベースに比べてとても便利になりました。awaitに対応できるようになります。動作が保証されるモダンなパッケージとバージョン管理(※ここで非同期というのは主にファイルやネットワークのIOが非同期であるという意味で使います。)しかしながら、Nodeを書くための言語はJavaScriptということに変わりはなく、実際にサーバーを書いたり、テストしていると、JavaScriptの言語仕様にゆるさから、もう少し新しい設計の言語を使いたくなってくる気持ちもあります。それでもJS(v8エンジン)自体は今では高速かつ安定に動作し、Nodeの発展と実用性の証明に貢献してきたと思いますが。弊社で提供している法人向けカメリオAPIはGoを使って実装されています。高速(実行・コンパイル)言語仕様はC言語に近い非同期動作はライブラリ依存パッケージ管理のような特徴があります。Goはかなりよく動いてくれましたが、Nodeに比べると、言語仕様が少し弱く、特に機能追加・変更の多いカメリオアプリのAPIにはあまり向かないように思います。(実際、NodeからGoの置き換えも検討しましたが見送りました)逆に、法人向けAPIのような機能追加や変更が少ない、常に安定させるサービスにはとてもよいです。強い表現力コンパイルが遅い(現状)非同期動作はライブラリ依存モダンなパッケージとバージョン管理のようなものがあります。iOSですでに使っている方ならお分かりですが、言語の設計が新しく、とても強力です。状況に応じて使えるさまざまなパターン(石川さんのスライドが詳しい)が使えるため、簡潔かつ安全に書けるようにもなります。それでいても、コードと見た目が短いところも大きいです。逆にいえば、新しく・強力な言語であるため、言語仕様の拡張や変更も大きく、学習コストもかなり大きいことに違いはありません。そこに関しては社内で継続的に勉強会をしたり、コードレビューをする必要がありますね。基本言語やフレームワークを移行するのは、どうしてもやりたい人が中心に社内をドライブしていかないと、うまくいかないと思います。SwiftでWebサーバーを作るには何が必要でしょうか。サーバーは出力にJSONのみを扱うため、HTMLについてはレンダリングできなくてもよいです。だいたいこのくらいのライブラリが必要になってくると思います。RPCクライアント現状のAPIを移植する場合、ORMまでは必要ないですが、Nodeのmysqlのような最低限のものがあるといいです。RPCクライアントはバックエンドのサーバーと通信するときに使いますが、無ければ自分で作ってもいいかもしれません。既知の問題は、各ライブラリがうまく非同期または何かの仕組みの上で、IOをブロックせずに動くかです。同期動作のライブラリはいくつかありますが、折角なので非同期のような仕組みに対応したライブラリを使いたいものです。最近を見ていると、サーバーのライブラリはZewoが活発に動いているようです。Webサーバー一式はもちろん、テンプレートエンジン・SSL・SQLなど一通り作られています。RedisもGithubで探すといくつかあります。SwiftのMySQLのクライアントもすでにいくつかあるのですが、node-mysqlっぽく使えて、しっくり来るものが欲しかったので作ってみました。これをベースに既存のサービスを実験的に実装してみたいと思います。novi/mysql-swiftクエリは生のSQLですが、クエリー文と結果のModelに関してはなるべくSwiftの型システムを使えるようにしました。今のところCベースのlibmysqlclientを使用しているので、Nodeのように非同期IOとまではいきませんが、ある程度型ができてきたら、非同期も対応する予定です。Swiftで使える非同期のMySQLクライアントライブラリが無いので、プロトコルも実装するしかないかな...まだまだLinuxやサーバーサイドのSwiftは始まったばかりです。NodeのExpressやKoaのように、Middlewareの設計のパターンも型が決まってない状態です。Swiftの便利さをサーバーサイドでも使いたい人が増えればライブラリも増えてくるかもしれません。基本的にはNodeのエッセンス(非同期・小さいライブラリなど)を踏襲しつつ、Swiftの型を取り入れたいと思います。ニュースアプリ「カメリオ」、レコメンドエンジン「カメクト」を提供する白ヤギコーポレーションのR&D部門として、データサイエンスの力でこの問題を解決していきます。白ヤギでは現在研究開発メンバーを募集しております。