VaporアプリケーションでAPIを作る(POST準備)

はじめに

GET編でデータの取得を行いました。でもこのままでは決まったものしか取得できません。いわゆる一方通行でサーバにあるデータを取ってくるだけの状態です。

今回はサーバへデータを送ってみます。これができれば、双方向でデータのやり取りができるようになります。公式ドキュメントを傍らにおいて試してみます。もはや言うまでも無いですが、手探りで進んでいきます。手探りすぎて進みが遅い。

データのモデルを作る

まずデータのモデルを作ります。Contentプロトコルに準拠させます。構造体かクラスどちらでも良さそうですが、ここは構造体で。扱うデータはJSONを想定します。ContentプロトコルはJSONのデコードとエンコードに対応しています。

struct Book: Content {
    var title: String
    var publish: String
    var price: Int
    init(title:String, publish:String, price:Int) {
    self.title = title
    self.publish = publish
    self.price = price
}

サンプルで本を表すモデルを作りました。タイトルと出版社、価格を管理します。併せて初期化メソッドも作っておきます。

作ったモデルでデータを返してもらう

まずは、サーバにデータがある状態でそれを返してもらいます。具体的には作ったデータモデルを返してもらうRouteを作ります。

router.get("Books") { req -> Book in
    let book = Book(title: "吾輩は何かである", publish: "猫猫出版", price: 650)
    return book
}

猫猫出版の吾輩は何かであるは今適当に作りました。ただの架空の本です。実在したらどうしよう……
http://localhost:8080/books にアクセスすると吾輩は何かであるという架空の本にJSONが帰ってくるはずです。

予定通りJSONが帰ってきました。

データをサーバに渡す

事前に指定されたデータが得られることは分かりました。次はサーバにデータを渡してみます。これまで使っていたのはGETですが、ここからはPOSTが出てきます。

router.post(Book.self, at: "api/book") { (req, data) -> Future<Book> in
    return Future.map(on: req) { () -> Book in
        return data
    }
}

atで示したパスでJSONをPOSTすると、非同期通信が行われてブーメランの如くdataに納まって戻ってきます。

ちょっとまって…… 正直に白状すると、自分でも何を言っているのか分かりません。わからない点をまとめてみます。

  • どうやってJSONを渡すの?
  • 突然出てきたFutureって何者?
  • Future.mapとは?(SwiftのcompactMapやflatMapとかと一緒かい?)

まとめ

なかなかDBまでたどり着きません。そして頭が追いつきません。ですが、この辺りをきっちり押さえておかないといけない気がします(経験上)。疑問点を先に片付けようと思います。