Backbone.jsでAPIに渡すときのメモ。

Backbone.jsでAPIに渡すときのメモ。

Backbone.sync とは

Backbone.sync とはBackboneがモデルからデータを取得したり保存したりする際に使う関数。
デフォルトでは、jQUery.ajaxを使ってRESTful JSON リクエストを送信し、jqXHRを受け取る。
また、オーバーライドも可能。

—————————-
RESTful とは

ウェブサービスのひとつの形

・明示的に HTTP メソッドを使う
・ステートレスにする
・ディレクトリー構造に似た URI を公開する
・XML、JSON (JavaScript Object Notation) のいずれか、またはその両方を転送する

jqXHR とは

XMLHttpRequestオブジェクトを一般化し、クロスブラウザ対応を行ったjQuery独自のオブジェクト。

—————————-

sync()の基本形

sync(method, model, [options])

method – the CRUD method ("create", "read", "update", or "delete")
model – the model to be saved (or collection to be read)
options – success and error callbacks, and all other jQuery request options


そしてmethodの部分は、

create → POST
read → GET 
update → PUT
delete → DELETE

これらが入る。

そして今回のようにbackboneで得たデータを、APIで保存するために送る時には、

Backbone.Model.save()
を使うとよい。

save()の中で.sync()に渡り、APIとの通信が行われる。

試しにこの様なコードを書いて、みたところ、

Model.url = '/apipath/';

var data = {'name':'hoge'};
Model.set(data);
Model.save(null, {
	success:function(){
		console.log('success.')
	},
	error:function(){
		console.log('error....');
	}
})

apiの方で$_POSTが空な事に気づく。

Developer toolでNetworkを見ても、Request MethodはPOSTだし、Request Payloadに値も入っている。

ググって見ると、この記事に辿り着いた。

http://shusatoo.net/programming/php/backbone-model-save-postdata-read-php/

こちらにより、$_POST ではapplication/jsonのPOSTが取得出来ないという事を知る。
通常、phpでフォームのPOSTを受け取る時には、Content-Type: application/x-www-form-urlencoded という形式が想定されているので、$_POSTでの受け取りが可能になっている。
Backboneでは、上述のようにjsonリクエストを送信するため$_POSTでは受け取れないのだと思われる。


そこで、解決策はというと、

1."php://input"から、リクエストボディを直接受け取る。
2.Backnone.emulateJSON = trueに設定する。

の2通りがあるそうだ。

1."php://input" とは
読み込み専用のストリームで、 リクエストの body 部から生のデータを読み込むことができます。 POST リクエストの場合は $HTTP_RAW_POST_DATA よりも php://input を使うのが望ましいでしょう。php.ini ディレクティブの設定に依存しないからです。

参考: http://php.net/manual/ja/wrappers.php.php


2.Backnone.emulateJSON とは

If you're working with a legacy web server that can't handle requests encoded as application/json, setting Backbone.emulateJSON = true; will cause the JSON to be serialized under a model parameter, and the request to be made with a application/x-www-form-urlencoded MIME type, as if from an HTML form.

意訳:
もしapplication/jsonでエンコードされたデータを扱えないようなレガシー・ウェブサーバーであるなら、Backbone.emulateJSON = trueにセットすべきだ。 そうすればJSONはシリアライズされてリクエストはHTMLフォームのような、application/x-www-form-urlencoded MIME 形式で渡される。


どちらでも良さそうだが、今回はファイルアップロードなんかもないのでapplication/x-www-form-urlencodedで渡す必要はない。記事にならい、php://inputの方法を使う。

この場合、受け取るAPIでは、

$postedData = json_decode(file_get_contents('php://input'), TRUE);

のように受け取れば、正しく渡る。

また一つ疑問が解消された。ありがとうございます!