はじめに
どうもどうも。API初心者です。失礼します(拝み手)。
他者が公開しているAPIを使うことはあっても、APIを公開する側に回るとは思いもしなかったです。
サーバサイドからMongoDBへアクセスするサーバサイドアプリケーションを作ってみました。が、サーバサイドアプリケーションの構築経験がほぼ無い状態で足元がグラグラの状態です。
このまま進めばグダる未来が現実のものとなるので、そうならないように足回りを固めようと思います。
セキュリティ関係のことはここでは触れませんので、ご注意を。あくまでも一時的かつローカルで試すことを目的に据えています。
まずはスッピンで動かす
何もしない状態でXCodeでRunすると、http://localhost:8080
でアプリケーションが動くようになります。実行すると、このような感じ。
![Vaporアプリケーションを初期状態で動かしたときの結果](https://s-cape.dev/wp-content/uploads/2020/05/886fdd7b132425c559a402ff9f29aa44.png)
Routeを追加する
もともと生成されているroutes.swift
にRouteを追加してみます。
これで、It works!以外を表示させてみます。
router.get("hello") { req in
return "Hello, world!"
}
router.get("hello/test") { req in
return "Hello, test!"
}
XCodeでRunからのhttp://localhost:8080/hello
とhttp://localhost:8080/hello/test
の結果です。
![routeを追加(http://localhost:8080/hello)](https://s-cape.dev/wp-content/uploads/2020/05/9f3e834d47fb8f3f3da849d08f1b651d.png)
![routeの追加 失敗例(http://localhost:8080/hello/test)](https://s-cape.dev/wp-content/uploads/2020/05/49ba6e7c340fa1a88b4a97d87d84e644.png)
Oops!
router.get("hello","test") { req in
return "Hello, test!"
}
![routeの追加 成功例(http://localhost:8080/hello/test)](https://s-cape.dev/wp-content/uploads/2020/05/40c4d5b324b9c2b8d03059cd89135ce0.png)
パラメータを渡してみる
まずはベーシックに文字列型から
ツーと言えばカー、山といえば川のような定型のやり取りだけでは物足りないです。パラメータを渡してみましょう。さっきのrouteを修正します。
router.get("hello",String.parameter) { req -> String in
let param = try req.parameters.next(String.self)
return "Hello, \(param)!"
}
先ほどtest
と入れたところに任意の文字列を入れてみます。試しにparameterを入れてみます。
![routeを追加(パラメータを渡す)](https://s-cape.dev/wp-content/uploads/2020/05/6b24eae79b9f3b97ac7e902414258c82.png)
日本語もいけますね。
![routeを追加(日本語パラメータを渡す)](https://s-cape.dev/wp-content/uploads/2020/05/956bf743570f9a9c09b5006cadb628d3.png)
型を変えてもいけますよ
StringではなくIntに変えてみます。
router.get("hello",Int.parameter) { req -> String in
let param = try req.parameters.next(Int.self)
return "Hello, \(param)!"
}
![routeを追加(Int型のパラメータを渡す)](https://s-cape.dev/wp-content/uploads/2020/05/976fa2d53e8e6f04e2c78551d9b1c30d.png)
ただし、このケースでhttp://localhost:8080/hello/abc
など数字以外が入ったときはエラーになります。
The parameter was not convertible to an Int
型には気をつけたほうがいいかもしれない
利用する人がお行儀良いかどうかは不確定です。いろんな人が居ます。
ですので、ひとまず文字列で受け取り、コード内で処理したほうがいいかもしれません。
router.get("hello",String.parameter) { req -> String in
let param = try req.parameters.next(String.self)
// 数字を受け取るつもりだったなら、ここでパースする。
return "Hello, \(param)!"
}
データを取り回す構造体を作る案もありますが、心配ならばパースするなどの対策を入れておくのがいいかもしれません。
注意
同じルートで型だけ変えてみるオーバロードのようなものはできないです。例えば、このような形はうまくいきません。
router.get("hello",String.parameter) { req -> String in
let param = try req.parameters.next(String.self)
return "Hello, \(param)!"
}
router.get("hello",Int.parameter) { req -> String in
let param = try req.parameters.next(Int.self)
return "Hello, \(param)!"
}
このようにしてしまうと、常に2つ目のrouteに入ってしまいます。そして、2つ目のrouteに入るにも関わらず、Vapor側では入力されているパラメータをString
とみなしているようです。推測ですが、コード上Int
だとしているのにVapor側はString
と認識しているということになり、型が違うというエラーが発生してしまいます。
Invalid parameter type: int != string
素直にrouteを変えるか、一律文字列で受け取ってコード側で何とかするのが良さそうです。
まとめ
今日はGETだけでここまでにします。次はAPIっぽくデータのPOSTを試してみます。徐々にDBサーバに向けて進めていきます。