MongoDBからデータをDELETEしてみる

MongoDBからデータをDELETEしてみるMongoDB
MongoDBからデータをDELETEしてみる

はじめに

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の処置が雑。もう少し丁寧に処置する習慣を付けないと!

動かしてみる

いざ削除。

削除のためのAPIを渡し、サーバ側から得られた結果
削除できたような感じがします

多分できたはず。削除が成功してようが失敗してようが、処理が済んだらVaporアプリケーション側から200ステータスが返されるへっぽこ仕様なのです。なので実際のコレクションの中身を見てみるまで安心できません。

MongoExpressを見て確認します。

削除対象としたドキュメントが消えていることをMongoExpressで確認した
削除対象としてドキュメントが消えています

まとめ

無事DELETEで削除もできるようになりました。

併せて例のへっぽこ仕様を軽く修正してみました。削除成功時は200ステータスを返しますが、失敗したときは代わりにnoContentというものを返すようにしてみました。ただし、適切かどうかが分からない。削除対象のドキュメントがなかったという意味合いでは合っていそうですが、少し違和感が残ります。DELETEに限らずGETやPOSTについても、実用上はもう少し細かくサーバから返される結果を見る必要がありますね。

タイトルとURLをコピーしました