REST APIで使用すると、symfony2フォームで動作するように投稿データを操作する
質問
バックグラウンド:
SymfonyにRestful APIを書いています。コンテンツタイプアプリケーション/JSONを使用して、クライアントにURLに投稿し、コントローラーアクションが探しているフォームのJSONオブジェクトを投稿できるようにしたいと考えています。
これにかなり基本的なコントローラーセットアップを使用しています。デモンストレーションの目的で、単純なユーザー名のパスワードコンボを認証しようとしていると仮定しましょう。
public function loginAction( Request $request )
{
$user = new ApiUser();
$form = $this->createForm(new ApiUserType(), $user);
if ( "POST" == $request->getMethod() ) {
$form->bindRequest($request);
if ( $form->isValid() ) {
$em = $this->getDoctrine()->getEntityManager();
$repo = $this->getDoctrine()->getRepository('ApiBundle:ApiUser');
$userData = $repo->findOneByUsername($user->getUsername());
if ( is_object($userData) ) {
/** do stuff for authenticating **/
}
else{
return new Response(json_encode(array('error'=>'no user by that username found')));
}
else{
return new Response(json_encode(array('error'=>'invalid form')));
}
}
}
さて、私が持っている問題、そして私が牛が帰宅するまでこれをvar_dumpingしようとしたことは、Symfonyがアプリケーション/JSONコンテンツボディを取得し、そのデータを使用してフォームデータを入力したくないということです。
フォーム名:API_APIUSER
フィールド:ユーザー名、パスワード
このタイプのタスクを処理するための最良の方法は何ですか。これを機能させることができる限り、私は提案を受け入れています。問題にご協力いただきありがとうございます。
解決 2
私は実際にこれを修正する同様の方法を見つけました。メソッドが投稿されているかどうかを確認した後、フォームにリクエストをバインドする前に、これを行います。
if ( "POST" === $request->getMethod() ) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')){
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
$form->bindRequest($request);
/** Rest of logic **/
}
他のヒント
生のリクエスト本体にアクセスしてから、json_decodeを使用する必要があります。おそらくあなたを変える必要があります bindRequest
次のような方法:
public function bindRequest(Request $request)
{
if($request->getFormat() == 'json') {
$data = json_decode($request->getContent());
return $this->bind($data);
} else {
// your standard logic for pulling data form a Request object
return parent::bind($request);
}
}
私は本当にSF2を台無しにしていないので、これはAPI、Expに基づいてより推測しています。 SF1.xと物事は、フレームワークのプレゼンテーションから獲得しました。また、ようなまったく異なる方法を作成する方が良いかもしれません bindJsonRequest
したがって、物事はもう少し整頓されています。
ええ、バインディング中にフォームが待っているのは、アピウスの特性に対応するキーを含む配列です。
したがって、文字列でPOSTリクエストを送信する場合:
{ username: 'user', password: 'pass' }
あなたはそれを使用してそれを配列に変換する必要があります json_decode
例えば:
$data = json_decode($request->getContent()); // $request->request->get('json_param_name');
次に、この配列を使用してフォームにバインドします $form->bind($data);
フォームは、配列のキー(ユーザー名、パスワード)に対応するApiuserプロパティを更新します。
RESTFUL JSON APIを構築している場合は、シリアル化器/トランスを使用してこのプロセスを自動化するようアドバイスします。 https://github.com/schmittjoh/jmsserializerbundle/blob/master/resources/doc/index.rst