はじめに
GET、POSTと来ればDELETEも! 今回も削除対象のドキュメントをコードベタ打ちで指定します。ジャブ打ち。
前提条件はこれまで同様、MongoDBからデータをGETしてみた時と同じです。
DELETEまでの道のり
削除対象のドキュメントを特定する
MongoExpressで削除したいドキュメントのIDを調べます。IDはドキュメントの追加時に自動的に採番されるようです。
ここではこのドキュメントにしましょう。
データをDELETEするメソッドを作る
func delete(id:String) {
let url: URL = URL(string: [接続先アドレス] + "/" + id)!
var request = URLRequest(url: url)
request.httpMethod = "DELETE"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task:URLSessionTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
// コンソール出力
if let dataString = data {
print("data:" + (String(data: dataString, encoding: .utf8) ?? "nilです"))
}
print("response: \(String(describing: response))")
print("error: \(String(describing: error))")
}
task.resume()
}
引数には先ほど調べたIDを渡します。
DELETEにおけるキモは削除対象のデータをどう渡すかというところでしょうか。
今回はURLに引っ付けて渡しています。これはAPIを受けるVaporアプリケーション側に合わせたものです。APIを受ける側の作りによっては、JSONデータで渡したり、パラメータで渡したりなど、状況は変わります。
(参考)Vaporアプリケーション側の削除処理
ちなみに、Vaporアプリケーション側の削除処理はこのような感じです。
router.delete("api/book",String.parameter) { req -> HTTPStatus in
let client = try! req.make(MongoClient.self)
let collection = client.db([データベース名]).collection([コレクション名], withType: Book.self)
let id = try req.parameters.next(String.self).lowercased()
let query:Document = try Document.init(fromJSON: "{\"_id\": {\"$oid\":\"" + id + "\" }}")
_ = try! collection.deleteOne(query)
return .ok
}
自動採番されるIDを使うときは、$oid
をキーとして指定した上で、対象となるドキュメントを検索する条件に渡すことに注意です。
そしてtry
の処置が雑。もう少し丁寧に処置する習慣を付けないと!
動かしてみる
いざ削除。
多分できたはず。削除が成功してようが失敗してようが、処理が済んだらVaporアプリケーション側から200ステータスが返されるへっぽこ仕様なのです。なので実際のコレクションの中身を見てみるまで安心できません。
MongoExpressを見て確認します。
まとめ
無事DELETEで削除もできるようになりました。
併せて例のへっぽこ仕様を軽く修正してみました。削除成功時は200ステータスを返しますが、失敗したときは代わりにnoContent
というものを返すようにしてみました。ただし、適切かどうかが分からない。削除対象のドキュメントがなかったという意味合いでは合っていそうですが、少し違和感が残ります。DELETEに限らずGETやPOSTについても、実用上はもう少し細かくサーバから返される結果を見る必要がありますね。