Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【vte.cx入門】6.登録したデータの内容を上書き・更新する:jQuery実践編

More than 5 years have passed since last update.

データの登録データの参照ができるようになったら、今度は参照したデータを更新してみましょう。

ここではjQueryを利用したデータの更新方法を記します。

1.更新するデータを準備する。

サーバから更新したいデータを取得してください。

仮に以下のデータとします。

{"feed" : {
    "entry" : [
        {
          "userinfo" : {
              "id" : 1234,
              "email" : "hoge@foo.com"
          },
          "favorite" : {
              "food" : "りんご",
              "music" : "J-POP"
          },
          "author" : [{"uri" : "urn:vte.cx:created:21"}],
          "id" : "/11/0-8-2-9-1-1-1,1",
          "link" : [{"___href" : "/11/0-8-2-9-1-1-1","___rel" : "self"}],
          "published" : "2015-12-01T13:44:46.067+09:00",
          "updated" : "2015-12-01T13:44:46.067+09:00"
        }
    ]
}}

更新内容は、favoriteのfood項目を「みかん」に書き換えてみます。

feed.entry[0].favorite.food = 'みかん';

2.ajaxでデータを更新する(PUTリクエスト)

上記データをjQueryのajax通信を使用し、PUTリクエストを実行します。

javascript
var request = {"feed" : {"entry" : [{"userinfo" : {"id" : 1234,"email" : "hoge@foo.com"},"favorite" : {"food" : "みかん","music" : "J-POP"},"author" : [{"uri" : "urn:vte.cx:created:21"}],"id" : "/11/0-8-2-9-1-1-1,1","link" : [{"___href" : "/11/0-8-2-9-1-1-1","___rel" : "self"}],"published" : "2015-12-01T13:44:46.067+09:00","updated" : "2015-12-01T13:44:46.067+09:00"}]}};

$.ajax({
    url: '/d/',
    method: 'put',
    dataType: 'json',
    data: JSON.stringify(request)
}).done(function(res) {
    alert('更新成功');
}).fail(function( jqXHR, textStatus, errorThrown ) {
    alert('更新失敗');
});

■リクエスト

param
url /d/
method PUT
dataType json
data 更新データ 上記参照

更新先はlinkタグのrel="self"で指定する【ポイント】

ajaxのリクエストURLが「/d/」なのに注目してください。
更新先はajax通信のリクエストURLを見るのではなく、データのlink項目のrel="self"のhref属性を元に実行します。

link項目のrel="self"の例
"link" : [{"___href" : "/11/0-8-2-9-1-1-1","___rel" : "self"}]  ← このhrefが更新先になる

更新するデータのlink項目のrel="self"と、更新したいデータのlink項目のrel="self"のhref属性が一致していることを必ず確認してください。

■レスポンス

成功ステータス

ステータス メッセージ レスポンス
200 OK {"feed" : {"title" : "Updated."}}

このレスポンスが返って来れば、正しく更新ができたということになります。
サーバからデータを取得して更新内容が正しく反映されているか確認しましょう。

データの更新が成功するとリビジョン番号が更新される【ポイント】

vte.cxでは登録データの管理をリビジョン管理で行っており、リビジョン番号がサーバと同一であれば更新を実行できます。
リビジョン番号はid項目の「,(カンマ)」の後ろに格納されています。

リビジョン番号の例
"id" : "/11/0-8-2-9-1-1-1,1"   ←   リビジョン番号は「1」

更新が成功すると、リビジョン番号がカウントアップします。

"id" : "/11/0-8-2-9-1-1-1,1"   ←   更新前

 ↓   更新成功

"id" : "/11/0-8-2-9-1-1-1,2"   ←   更新後

 ↓   さらに更新

"id" : "/11/0-8-2-9-1-1-1,3"   ←   このようにカウントアップされる

こうしたリビジョン管理を行うことで、最新のデータを正しく管理しています。

リビジョン番号のカウントアップはサーバが自動で行います。

ユーザはサーバのリビジョン番号が更新データのリビジョン番号と一致しているかどうかだけを確認していただければ大丈夫です。

失敗ステータス

以下の仕様書の下部に細かく記載されています。ステータスコードに沿って正しいデータを登録してみてください。
HTTPステータス一覧

ステータス:409になった場合【ポイント】

このエラーは楽観的排他チェックが行われた結果起こることがあります。
つまり、データの競合が発生したケースになります。

データの競合とは

同じデータを同時に更新しようとして起こるエラーです。
自分が保持していたデータが古くなってしまい、リビジョン番号がサーバと一致せずに更新の実行できなくなってしまう状態です。

データの競合が起きてしまった場合の回避策
【方法1】最新のデータを取得し直す

データの競合が起きてしまった場合は、もう一度サーバから最新のデータを取得し、そのデータに沿って更新を行ってください。

【方法2】リビジョン番号のみをサーバのデータと一致させる

もう一つは、サーバのデータのリビジョン番号と更新データのリビジョン番号のみを一致させる方法です。
リビジョン番号がサーバと一致さえすれば更新は実行できるので、状況によっては必ずしもすべてのデータを最新の内容にする必要はありません。

"id" : "/11/0-8-2-9-1-1-1,23"   ←   サーバのリビジョン番号
"id" : "/11/0-8-2-9-1-1-1,20"   ←   更新しようと思ったデータのリビジョン番号

 ↓   リビジョン番号を一致させる

"id" : "/11/0-8-2-9-1-1-1,23"   ←   更新するデータのリビジョン番号

楽観的排他処理を行わずに強制的に上書きする

PUT更新では強制的に上書きする方法があります。
以下のようにid項目を省略して更新することができます。

id項目を省略した更新データの例
{"feed" : {
    "entry" : [
        {
          "userinfo" : {
              "id" : 1234,
              "email" : "hoge@foo.com"
          },
          "favorite" : {
              "food" : "りんご",
              "music" : "J-POP"
          },
          "author" : [{"uri" : "urn:vte.cx:created:21"}],
          "link" : [{"___href" : "/11/0-8-2-9-1-1-1","___rel" : "self"}],
          "published" : "2015-12-01T13:44:46.067+09:00",
          "updated" : "2015-12-01T13:44:46.067+09:00"
        }
    ]
}}

この場合、楽観的排他チェックは行われず、常に上書き更新になります。
強制的に上書きされることでデータが失われることもありますのでidを省略するのはなるべく避けた方がいいでしょう。

終わりに

データの更新時は、必ずそのデータが最新かどうかを必ずチェックし、競合が起こらないようにコントロールしていく必要があります。
リビジョン番号をどのようにサーバと同期させるのかは、作成するアプリによって方法は変わると思うので、その都度方法を検討してみてください。

以上で、更新の方法についての説明を終わりたいと思います。

更新についてより詳しく知りたい方は仕様書をご参照ください。

次回はサーバのデータ削除の方法です。

takeyama
AngularJS始めたばかりの初心者です
http://reflexworks.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away