2013-05-16 4 views
9

私は単純なAPIを書いており、このAPIの上に簡単なWebアプリケーションを構築しています。Laravel 4で手動でディスパッチしたリクエストのクエリ文字列パラメータにアクセスするにはどうすればよいですか?

私が直接、「私自身のAPIを消費」したいので、私が最初にGoogleで検索し、完全に私の最初の質問に答えるStackOverflowの上でこの答えを見つけました:Consuming my own Laravel API

は今、これは素晴らしい作品、私は自分にアクセスすることができますよAPIは次のようにすることで実現します:

$request = Request::create('/api/cars/'.$id, 'GET'); 
$instance = json_decode(Route::dispatch($request)->getContent()); 

これは素晴らしいです!今、私は実際にAPIでこれを処理する方法を

http://cars.com/api/cars/1?fields=id,color 

:しかし、私のAPIにもこのような返されるべき特定の属性を指定するGETクエリ文字列にオプションのフィールドパラメータを追加することができます

$request = Request::create('/api/cars/' . $id . '?fields=id,color', 'GET'); 
$instance = json_decode(Route::dispatch($request)->getContent()); 

public function show(Car $car) 
{ 
    if(Input::has('fields')) 
    { 
      //Here I do some logic and basically return only fields requested 
      .... 
    ... 
} 

私は、前にクエリ文字列パラメータレスのアプローチでこのような何かをしたと私は似た何かができることを前提としています。この線に沿って何かであります

しかし、そうは思われません。長文で言えば、コードをステップ実行すると、Requestオブジェクトが正しく作成されているように見えます(のフィールドのパラメータを正確に引き出し、のid、色を割り当てます)、ルートはディスパッチされたようですが、私のAPIコントローラ自体の中でフィールドパラメータにアクセスする方法がわかりません。 Input::get('fields')(私が "通常の"要求に使用しているもの)を使用すると何も返されません。静的なInputが最初の要求を参照しているか、またはスコープしているからです。アプリ内で

私の質問は本当にどうすればいいのですか?私は何か間違っているのですか?理想的には、私のAPIコントローラで醜いものや特別なものをするのを避けたいのですが、内部でディスパッチされたリクエストに対してInput :: getを使用できるようにしたい、もう一度チェックする必要はありません。

答えて

18

Inputを使用して実際に現在の要求を参照していて、新しく作成した要求を参照していないという点で正しいです。あなたの入力は、Request::create()でインスタンス化するリクエストインスタンス自体で利用可能になります。

Illuminate\Http\Requestを使用してリクエストをインスタンス化する場合は、$request->input('key')または$request->query('key')を使用して、クエリ文字列からパラメータを取得できます。

ここでの問題は、あなたのIlluminate\Http\Requestインスタンスがルートに存在しない可能性があることです。ここでの解決策(つまり、ファサードをInputに引き続き使用できるようにする)は、現在の要求の入力を物理的に置き換えてから元に戻すことです。

// Store the original input of the request and then replace the input with your request instances input. 
$originalInput = Request::input(); 

Request::replace($request->input()); 

// Dispatch your request instance with the router. 
$response = Route::dispatch($request); 

// Replace the input again with the original request input. 
Request::replace($originalInput); 

これは(理論的に)動作するはずですし、あなたの内部API要求が行われる前と後のあなたはまだ元の要求の入力を使用することができるはずです。

+0

一つのこと内部要求が別の内部要求を呼び出す可能性があります。スタックの要求を保持し、元の入力を保存し、スタックから最後の要求をポップし、それに応じて入力を置き換える必要があるかもしれません。 –

+0

作成されたリクエストにヘッダーを添付する方法はありますか?たとえば、リクエストとともに公開APIキーを送信する方法はありますか? – whonoes

2

私もこの問題に直面していました。ジェイソンの偉大な答えのおかげで、私はそれを動作させることができました。

ルートを置き換える必要があることがわかりました。それ以外の場合は、Route::currentRouteName()が、スクリプトの後半にディスパッチされたルートを返します。

これ以上の詳細は私のblog postにあります。

私はまた、スタッキングに関するいくつかのテストを行い、このアプローチで互いに内部APIメソッドを繰り返し呼び出しました。それはうまくいった!すべてのリクエストとルートが正しく設定されています。

+0

THanks for the info! ええ、私は、基本的に何もしない単純なモデルを作成しましたが、基本的には、リクエストを実行した後で自動的にこれらのデータを交換します。 もう一度情報をお寄せいただきありがとうございます。 –

+3

このurlは404を返します – Tom

0

あなたは内部APIを呼び出すと、(代わりに、クエリ文字列の)配列を経由してパラメータを渡したい場合は、次のように行うことができます。

$request = Request::create("/api/cars", "GET", array(
    "id" => $id, 
    "fields" => array("id","color") 
)); 
$originalInput = Request::input();//backup original input 
Request::replace($request->input()); 
$car = json_decode(Route::dispatch($request)->getContent());//invoke API 
Request::replace($originalInput);//restore orginal input 

参考:心に留めておくべきLaravel : calling your own API

+0

Request :: replaceは存在しません – neoteknic

+0

@neoteknicそれを確認してくださいhttps://laravel.com/api/4.2/Illuminate/Http/Request.html – ThoQ

関連する問題