猿でもできるKituraでJSONを生成する方法

開発環境Xcode8.1
Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)

## はじめに
こんにちは。iRidge Advent Calendar19日目担当します。
Kituraについてです。タイトルの猿でもできるの意味については[こちら](http://thesaurus.weblio.jp/content/%E3%82%B5%E3%83%AB%E3%81%A7%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B)



## Kituraとは
A high performance and simple to use web framework for building modern Swift applications.
IBM社がOSSで公開しているSwiftのモダンWebアプリケーションフレームワークです。
[Kitura公式](http://www.kitura.io/)

## 目的
Kituraでレスポンスデータをjsonで返すまでを構築してアプリ開発をしたい。

# 導入
導入手順は[Kitura公式](http://www.kitura.io/)に記述してあるGetting Startedを参考

### 開発するフォルダを作成し以下コマンドを叩く

```
$ cd myKituraProject
$ swift package init --type executable
```

コマンドを叩くと以下のような形式で作成されます

```
myKituraProject
├── Package.swift
├── Sources
│   └── main.swift
└── Tests
```

Swift Package Managerについては[こちら](https://swift.org/package-manager)

### Pakage.swiftを編集

```swift
import PackageDescription

let package = Package(
    name: "myFirstProject",
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 4)
    ])
```

### Sources/main.swiftを編集

```swift
import Kitura

// Create a new router
let router = Router()

// Handle HTTP GET requests to /
router.get("/") {
    request, response, next in
    response.send("Hello, Kitura!")
    next()
}

// Add an HTTP server and connect it to the router
Kitura.addHTTPServer(onPort: 8090, with: router)

// Start the Kitura runloop (this call never returns)
Kitura.run()

```

### 以下コマンドを実行しコンパイルする

```
$ swift build
```

### 以下コマンドを実行しWebアプリケーションを実行する

```
$ .build/debug/myKituraProject
```

### Open your browser

ブラウザで以下urlを開くと `Hello, Kitura!`と表示されます :champagne: 

```swift
http://localhost:8090/
```

<img width="895" alt="スクリーンショット 2016-12-21 8.50.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/4fe5a41e-7a5b-08e2-edd3-ea97967e6cfe.png">


# ログを表示する

### Package.swiftにHeliumLoggerを追加

```swift
import PackageDescription

let package = Package(
    name: "myFirstProject",
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 4),
        .Package(url: "https://github.com/IBM-Swift/HeliumLogger.git", majorVersion: 1, minor: 4)
    ])
```

###  Sources/main.swiftにHeliumLoggerを初期化

```swift
import Kitura
import HeliumLogger

// Initialize HeliumLogger(これこれ追加)
HeliumLogger.use()

// Create a new router
let router = Router()

// Handle HTTP GET requests to /
router.get("/") {
    request, response, next in
    response.send("Hello, Kitura!")
    next()
}

// Add an HTTP server and connect it to the router
Kitura.addHTTPServer(onPort: 8090, with: router)

// Start the Kitura runloop (this call never returns)
Kitura.run()

```

### 同様にコンパイルから実行


```
$ swift build
$ .build/debug/myKituraProject
```
実行すると無事にログが出力されているのがわかります :champagne: 

```
[2016-12-21T01:00:46.632+09:00] [VERBOSE] [Router.swift:67 init(mergeParameters:)] Router initialized
[2016-12-21T01:00:46.657+09:00] [VERBOSE] [Kitura.swift:71 run()] Starting Kitura framework...
[2016-12-21T01:00:46.658+09:00] [VERBOSE] [Kitura.swift:81 start()] Starting an HTTP Server on port 8090...
[2016-12-21T01:00:46.659+09:00] [INFO] [HTTPServer.swift:85 listen(on:)] Listening on port 8090
```

# XcodeProject

### Package.swiftのディレクトリに移動しコマンドを実行

以下コマンドを実行

```
$ swift package generate-xcodeproj
```

MyKitura.xcodeprojが生成されます

```
myKituraProject
|-- MyKitura.xcodeproj
├── Package.swift
├── Sources
│   └── main.swift
└── Tests
```

### Schemeを選択して実行

カバンアイコンの下を選択して実行します

<img width="222" alt="スクリーンショット 2016-12-21 1.20.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/dd79cdaa-dba0-d6c5-0486-e40103ffed33.png">

実行するとXcodeデバッグエリアにログが表示されます(HeliumLogger実装前提)

<img width="1023" alt="スクリーンショット 2016-12-21 1.21.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/6812e6b9-30d7-2484-02bc-13be2c95bf5a.png">

### Open your browser

ブラウザで以下urlを開くと `Hello, Kitura!`と表示されます :champagne: 

```swift
http://localhost:8090/
```

# カスタムパスを作成

### Sources/main.swiftを編集

```swift

router.get("/test") { request, response, next in
    try response.send("Hello! Test.").end()
}

```

main.swiftを編集し、コンパイル->実行してからブラウザでhttp:localhost:9080/testで確認すると `Hello! Test.` が表示されています :champagne: 

<img width="903" alt="スクリーンショット 2016-12-21 8.51.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/12ef88a0-1a65-aa56-2361-2d1bbb09b028.png">

# JSONを作成

### SwiftyJSONをインポートする

Sources/main.swiftにおいて `SwiftyJSON` をインポートします

<img width="188" alt="スクリーンショット 2016-12-21 8.57.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/94a850c9-53b5-16f2-8145-4c43ff7d0b4c.png">

### JSON化したいデータをDictionaryで作成

```swift
let dict: [String: Any] = [
    "shop": "book_store",
    "Item": [
        "id": "5",
        "name": "iOS Tutorial",
        "value": "890"
    ]
]

```

### カスタムパスを作成

```swift
router.get("/json") { request, response, next in
    
    response.headers["Content-Type"] = "application/json; charset=UTF-8"
    try response.send(json: JSON(dict)).end()
}

```
SwiftyJSONの使用方法などは[こちら](https://github.com/SwiftyJSON/SwiftyJSON)

### ブラウザで表示

http:localhost:9080/jsonを叩いて確認するとjsonが表示されました :champagne: 


<img width="956" alt="スクリーンショット 2016-12-21 9.02.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/87941a7a-55b5-8ff7-dad7-6d8e4e4e9806.png">


### 動的にJSONを生成

## クエリストリングで付与したパラメータをjsonに反映させる

```swift
router.get("/json") { request, response, _ in
    let id = request.queryParameters["id"] ?? ""
    let dict: [String: Any] = [
        "shop": "bood_store",
        "Item": [
            "id": "\(id)",
            "name": "book",
            "value": "890"
        ]
    ]
    try response.send(json: JSON(dict)).end()
}

```

### ブラウザで表示

クエリストリングを付与させてurlを叩くと動的にjsonが生成されて表示されてます :champagne: 


`http:localhost:9080/json?id=123455 `

<img width="904" alt="スクリーンショット 2016-12-21 10.09.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/100514/fca76eda-e4c7-892f-ea5f-9c42babbece6.png">


# 所感


- 静的なjsonファイルをサーバにデプロイするだけであれば `FireBase` などmBaaSを使ったほうが手軽感はあると思った

- クエリストリングなど動的にJsonのvalueを変更して開発を行いたい時にはKituraは良い感じだと思った

- サーバサイドをSwiftでロジックを書いてCGIを作成する事もできるのは良い感じだと思った

# 最後に

iRidgeではエンジニアを募集しています。
興味のある方は[こちら](https://iridge.jp/rec/)