futoase

よろしくお願いします。

Server side Swiftに触れてみる

Server side Swiftに触れてみる

swift.org

昨年からServer side Swift という単語が見られるようになってきた。

Swift については 2014年のWWDCで発表されたプログラミング言語

iOS, macOS など Apple製品向けとして、また処理系は2015年末にOSSとして公開され、 現在はUbuntu上でもSwiftで作成した成果物を利用できる。

Swiftのオープンソース化、Swift 3.0のロードマップ

mobile開発向けの言語でもありserver sideでも利用できる。 Kotlinのようだ。Swiftについて以前から利用したいと思っていたが、手を出していなかった。 今回、最小限のものを作ってみて理解を深めようと思う。

開発環境

私が利用している開発環境/OSは

である。

処理系のインストール

homebrewを使ってSwiftをインストールする。

> brew install swift

まず、Hello world

何をつくるか、がわからない。とりあえずHello worldをやってみたい。 Swift 3.0からpackage-managerというパッケージを作る機能(Rustのcargoみたいな)があり、 library/module のスケルトン(ディレクトリ構造など)を作成してくれる。

Swift.org - Package Manager

ディレクトリを作り、moduleを作る

ディレクトリを作り、ディレクトリの中でコマンドを実行する。

> mkdir -p hello-world
> cd hello-world
> swift package init

swift package init
Creating library package: hello-world
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/hello_world.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/hello-worldTests/
Creating Tests/hello-worldTests/hello_worldTests.swift

moduleの成果物を生成、テストを行える状態になっている。

> swift build
Compile Swift Module 'hello_world' (1 sources)
> swift test
Compile Swift Module 'hello_worldTests' (1 sources)
Linking ./.build/debug/hello-worldPackageTests.xctest/Contents/MacOS/hello-worldPackageTests
Test Suite 'All tests' started at 2016-12-10 12:12:50.328
Test Suite 'hello-worldPackageTests.xctest' started at 2016-12-10 12:12:50.329
Test Suite 'hello_worldTests' started at 2016-12-10 12:12:50.329
Test Case '-[hello_worldTests.hello_worldTests testExample]' started.
Test Case '-[hello_worldTests.hello_worldTests testExample]' passed (0.003 seconds).
Test Suite 'hello_worldTests' passed at 2016-12-10 12:12:50.332.
         Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
Test Suite 'hello-worldPackageTests.xctest' passed at 2016-12-10 12:12:50.332.
         Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
Test Suite 'All tests' passed at 2016-12-10 12:12:50.332.
         Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.004) seconds

コマンドを作るには

コマンドを作るには、package オプションの引数を追加すれば良い

> swift package init --type executable
Creating executable package: hello-world
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/

executable オプションを付けると、main.swift のみが作成される。 main.swiftの中身は、print文のみだ。

print("Hello, world!")

ビルドし、成果物として出来上がったバイナリを実行することができる。

> swift build
Compile Swift Module 'hello_world' (1 sources)
Linking ./.build/debug/hello-world
> ./.build/debug/hello-world
Hello, world!

main.swift がエントリポイントになっている。 main.swiftをSourceの下に作成すれば、実行バイナリが生成される。

Web applicationを作る

簡素なWeb applicationを作ってみようと思う。

> mkdir simple-web-server-swift
> cd simple-web-server-swift
> swift package init

利用するlibrary

簡素なWeb server を作ることができるZewoを利用する。

github.com

パッケージの設定

Package.swift に依存関係を追加する。

import PackageDescription

let package = Package(
    name: "simple-web-server-swift",
    dependencies: [
        .Package(url: "https://github.com/Zewo/HTTPServer.git", majorVersion: 0, minor: 14),
    ]
)

main.swiftに書く

main.swift に書く。README.mdのものを使う。

import HTTPServer

let log = LogMiddleware()

let router = BasicRouter { route in
    route.get("/hello") { request in
        return Response(body: "Hello, world!")
    }
}

let server = try Server(port: 8080, middleware: [log], responder: router)
try server.start()

ビルドする

依存関係をいろいろと解決してくれる。

> swift build

ビルドが成功した。成果物としてのコマンドを実行する。

./.build/debug/simple-web-server-swift 



                             _____
     ,.-``-._.-``-.,        /__  /  ___ _      ______
    |`-._,.-`-.,_.-`|         / /  / _ \ | /| / / __ \
    |   |ˆ-. .-`|   |        / /__/  __/ |/ |/ / /_/ /
    `-.,|   |   |,.-`       /____/\___/|__/|__/\____/ (c)
        `-.,|,.-`           -----------------------------

================================================================================
Started HTTP server at 0.0.0.0, listening on port 8080.

サービスが立ち上がった。

f:id:syanbi:20161210133301p:plain

かなり気軽に作れた。

ドライバなど調べてみると...

AWS SDKを利用したいと思ったが、

AWS iOS SDK について Swift Package manager が対応していない。Package.swiftが無い... ので対応待ち。 cocoa podsを入れてやってみるというモチベーションはわかなかった。

DB用のドライバ

以下のものがあった。

Swift package managorに対応している。

その他のドライバについて

Perfect というWeb frameworkプロダクトがあり、 そのプロダクト内の成果物としてコネクタやライブラリがある。

Redisであれば以下。

https://github.com/PerfectlySoft/Perfect-Redis

言語としてのSwift

特徴

Optional (nil代入可能) や Null safety (?演算子によるnil参照)、型推論があること、があげられる。 qiita.com

サーバサイドで利用するときに気になる点

スレッドセーフ、Goのgoroutine, channelに準ずる機能の実装に関して 以下のドキュメントに書かれていた。

Concurrency.rst

要約すると

  • ネイティブ(APIを利用しない形)でのスレッドセーフのサポートレベルはC++と同程度
  • Stream, Taskを利用することでGoのchannel, goroutineと同等のことが行える
  • 非同期処理をサポート(async, await)
  • Actorによるメッセージ非同期処理をサポート

という感じだ。モダンだなこれ。

Copyright (c) 2013-2017 Keiji Matsuzaki