web-dev-qa-db-fra.com

Comment accéder aux paramètres de chaîne de requête pour les demandes que j'ai envoyées manuellement Laravel 4?

J'écris une API simple et je construis une application Web simple en plus de cette API.

Parce que je veux "consommer ma propre API" directement, j'ai d'abord cherché sur Google et trouvé cette réponse sur StackOverflow qui répond parfaitement à ma question initiale: Consommer ma propre Laravel API

Maintenant, cela fonctionne très bien, je peux accéder à mon API en faisant quelque chose comme:

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

C'est bien! Mais, mon API vous permet également d’ajouter un paramètre optionnel fields à la chaîne de requête GET pour spécifier les attributs spécifiques à renvoyer, tels que:

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

Maintenant, la façon dont je gère cela dans l'API ressemble à ceci:

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

Je supposerais que je pouvais faire quelque chose de similaire à ce que j'avais fait avec l'approche sans paramètre de chaîne de requête auparavant, quelque chose comme ceci:

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

MAIS, cela ne semble pas être le cas. En résumé, après avoir parcouru le code, il semble que l’objet Request soit correctement créé (et il extrait correctement le paramètre fields et lui attribue id, color ), et le La route semble avoir été envoyée, mais au sein de mon contrôleur API, je ne sais pas comment accéder au paramètre field . Utiliser Input::get('fields') (ce que j'utilise pour les requêtes "normales") ne renvoie rien, et je suis à peu près sûr que c'est parce que la variable statique Input fait référence à la requête initiale ou la portée de celle-ci, PAS la nouvelle requête que j'ai envoyée "manuellement" de dans l'application elle-même.

Donc, ma question est vraiment comment devrais-je faire cela? Est-ce que je fais quelque chose de mal? Idéalement, j'aimerais éviter de faire quoi que ce soit de moche ou de spécial dans mon contrôleur API, j'aimerais pouvoir utiliser Input :: get pour les demandes envoyées en interne et ne pas avoir à faire une deuxième vérification, etc.

9
Kevin Mitchell

Vous avez raison de dire que l'utilisation de Input fait en réalité référence à la demande actuelle et non à la demande que vous venez de créer. Votre entrée sera disponible sur l'instance de demande elle-même que vous instancierez avec Request::create().

Si vous utilisiez (comme vous devriez le faire) Illuminate\Http\Request pour instancier votre demande, vous pouvez utiliser $request->input('key') ou $request->query('key') pour obtenir les paramètres de la chaîne de requête.

Le problème est qu’il est possible que votre instance Illuminate\Http\Request ne soit pas disponible dans l’itinéraire. Une solution ici (pour que vous puissiez continuer à utiliser la façade Input) consiste à remplacer physiquement l'entrée de la requête en cours, puis à la rétablir.

// 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);

Cela devrait fonctionner (en théorie) et vous devriez toujours pouvoir utiliser votre entrée de demande initiale avant et après votre demande d'API interne.

18
Jason Lewis

Je faisais également face à ce problème et, grâce aux bonnes réponses de Jason, j'ai pu le faire fonctionner. 

Je voulais juste ajouter que j’ai découvert que la Route devait également être remplacée. Sinon, Route::currentRouteName() renverra la route distribuée plus tard dans le script.

Plus de détails à ce sujet peuvent être trouvés sur mon blog post .

J'ai également fait quelques tests pour le problème d'empilement et appelé des méthodes d'API internes à plusieurs reprises de l'intérieur avec cette approche. Cela s'est bien déroulé! Toutes les demandes et tous les itinéraires ont été définis correctement.

2
santacruz

Si vous souhaitez appeler une API interne et transmettre des paramètres via un tableau (au lieu d'une chaîne de requête), procédez comme suit:

$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

Ref: Laravel: appelez votre propre API

0
Tho