MongoDBへデータをPOSTしてみる

MongoDB
MongoDBへデータをPOSTしてみる

はじめに

GETができれば今度はPOSTだ!

テキストボックスとか並べてカッコよく行きたかったけど、コードベタ打ちでJSONをぶつけてみます。何事もジャブ打ちから。急いてはなんとやらです。細かく刻んでいきましょう。

前提条件はMongoDBからデータをGETしてみた時と同じです。

POSTまでの道のり

データモデルを作る

struct Book:Codable {
  var title:String
  var publisher:String
  var price:Int
}

データを受け入れるサーバ側に合わせてデータモデルを作ります。MongoDB相手なので、JSONで渡せばどんな中身でもいいと言えばそれまでなんですが、秩序は保っていきましょう。

ここでのキモはCodableです。このプロトコルに準拠していると、JSON処理がとてもラクになります。

Encoding and Decoding Custom Types | Apple Developer Documentation
Make your data types encodable and decodable for compatibility with external representations such as JSON.

データをPOSTするメソッドを作る

let encoder = JSONEncoder()
do {
  // 引数で渡されたデータモデルをJSONデータに変換
  let jsondata = try encoder.encode(data)
  let url: URL = URL(string: [接続先アドレス])!
  var request = URLRequest(url: url)
  // ヘッダ情報を指定する
  request.httpMethod = "POST"
  request.addValue("application/json", forHTTPHeaderField: "Content-Type")
  // JSONデータをリクエストに載せる
  request.httpBody = jsondata
  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()
} catch {
  print(error.localizedDescription)
}

なお、引数で先ほど作ったデータモデルを渡しています。

ベースはGETの時とほぼ同じです。コード内にコメントを書きましたが、

  • URLリクエストのBody部にJSONを載せること
  • ヘッダ情報を指定すること

がキモでしょうか。

なお、request.addValue("application/json", forHTTPHeaderField: "Content-Type")を忘れてしまうと、レスポンスでステータス400が返ってきます。コンソールに出てくるresponseにapplication/jsonが出ているので、何もせずともヘッダに設定されているものと思いきや、設定されていませんでした。

動かしてみる

ここが楽しいところ。動かしてみましょう!

コンソール上で200ステータスが返ってきているのがわかります
MongoExpressで確認すると、データが確かに追加されています

良い感じです!! 😀

参考に、request.addValue("application/json", forHTTPHeaderField: "Content-Type")を忘れた場合。

400ステータスが返ってきてしまってPOST失敗しています

Content-TypeにJSONの記載があるので、すっかり勘違いをしてしまいました。

まとめ

GETに引き続きPOSTも成功!この調子で更新と削除も試してみたいですね。並行して、UIの方もこだわってみたい。検索とかリストで表示とかしてみたい。

反省点

もう少しメソッドを切り分けたほうが良かったかもしれない。do-catchで大きく括りすぎた感があります。JSONデータを取得する部分とURLリクエストを組み立てる部分と実際にサーバへリクエストする部分に分けてみましょうかね。