web-dev-qa-db-fra.com

Consommer ma propre API Laravel

Je développe une application Laravel 4 qui rendra les mêmes opérations CRUD sur mon jeu de données disponibles via une API JSON REST et une interface utilisateur Web. Il semble que pour éviter de rompre le principe DRY selon lequel mon interface utilisateur doit consommer ma propre API en renvoyant toutes les demandes de l'interface utilisateur vers l'API. Je ne suis cependant pas sûr de la meilleure approche pour faire ce travail. Vraisemblablement, j'aurais des contrôleurs d'interface utilisateur et d'API distincts et acheminerais les requêtes. Ou devrais-je envisager une approche totalement différente?

Merci.

48
robjmills

En fait, je bricole avec la même idée et c'est plutôt chouette. Avec Laravel, vous avez la possibilité de faire des demandes internes (certains pourraient appeler cela HMVC, mais je ne le ferai pas). Voici les bases d'une demande interne.

$request = Request::create('/api/users/1', 'GET');

$response = Route::dispatch($request);

$response va maintenant contenir la réponse renvoyée de l'API. En règle générale, une chaîne codée JSON est renvoyée, ce qui est excellent pour les clients, mais pas pour les requêtes d'API internes. Vous devrez étendre quelques éléments ici, mais l’idée est essentiellement de renvoyer l’objet réel pour l’appel interne et, pour les demandes externes, de renvoyer la réponse JSON formatée. Vous pouvez utiliser des éléments tels que $response->getOriginalContent() ici pour ce genre de chose.

Ce que vous devriez regarder est de construire une sorte de Dispatcher interne qui vous permette de distribuer des requêtes API et de retourner l'objet original. Le répartiteur doit également gérer les requêtes mal formées ou les réponses erronées et émettre des exceptions pour correspondre.

L'idée elle-même est solide. Mais planifier une API est un travail difficile. Je vous recommande de rédiger une bonne liste de tous vos points de terminaison prévus et de rédiger quelques versions d'API, puis de sélectionner la meilleure.

44
Jason Lewis

NOTE: Comme vcardillo l'a souligné ci-dessous, les filtres de route ne sont pas appelés avec ces méthodes.

Je suis en train de faire la même chose et la réponse de Jason m'a fait avancer dans la bonne direction. En examinant la documentation Symfony\Component\HttpFoundation\Request , j'ai compris comment effectuer un POST, ainsi que tout ce dont j'avais besoin. En supposant que vous utilisiez un formulaire, voici un code qui pourrait vous aider:

OBTENIR:

$request = Request::create('/api/users/1', 'GET');

$response = Route::dispatch($request);

POSTER:

$request = Request::create('/api/users/1', 'POST', Input::get());

$response = Route::dispatch($request);

POST w/cookies

$request = Request::create('/api/users/1', 'POST', Input::get(), Cookie::get('name'));

$response = Route::dispatch($request);

POST w/fichiers

$request = Request::create('/api/users/1', 'POST', Input::get(), null, Input::file('file'));

$response = Route::dispatch($request);

J'espère que ça aidera quelqu'un d'autre. Si vous n'utilisez pas de formulaire ou n'utilisez pas la façade Entrée/Cookie de Laravel, remplacez les façades Entrée/Cookie par votre propre contenu.

24
Domenic Fiore

Si vous utilisez votre propre API, utilisez app()->handle() au lieu de Route::dispatch() comme l'a suggéré Derek MacDonald.

app()->handle() crée une nouvelle demande, alors que Route::dispatch() exécute la route dans la pile, en ignorant effectivement les paramètres faisant partie de la demande que vous envoyez.

Edit: Juste un avertissement. Taylor Otwell déconseille l'utilisation de sous-requêtes pour passer des appels d'API internes, car elles gâchent l'itinéraire actuel . Vous pouvez utiliser un client API HTTP comme Guzzle à la place pour effectuer les appels d'API.

2
jpcaparas

Vous pouvez utiliser Consommateur d’API Optimus , l’API est propre et simple, exemple pour effectuer une demande interne:

$response = app()->make('apiconsumer')->post('/oauth/token', $data);

En son cœur, il utilise Illuminate\Routing\Router et Illuminate\Http\Request pour effectuer l'appel.

// create the request
$this->request->create($uri, $method, $data, [], [], $server, $content);

// get the response
$response = $this->router->prepareResponse($request, $this->app->handle($request));
1
Walid Ammar

Si vous souhaitez utiliser l’API login de passeport en interne, vous devez ajouter les paramètres à la demande initiale:

    protected function manualLogin(Request $request)
    {
        $email = $request->input('email');
        $password = $request->input('password');

        $request->request->add([
        'username' => $email,
        'password' => $password,
        'grant_type' => 'password',
        'client_id' => $clientID,
        'client_secret' => $clientSecret,
        'scope' => '*']);

    $newRequest = Request::create('/oauth/token', 'post');

    return Route::dispatch($newRequest)->getContent();
}
1
Pankaj Garg

Si vous souhaitez utiliser l’API login de passeport en interne, vous devez ajouter les paramètres à la demande initiale:

protected function manualLogin(Request $request)
{
    $email = $request->input('email');
    $password = $request->input('password');

    $request->request->add([
        'username' => $email,
        'password' => $password,
        'grant_type' => 'password',
        'client_id' => $clientID,
        'client_secret' => $clientSecret,
        'scope' => '*']);

    $newRequest = Request::create('/oauth/token', 'post');

    return Route::dispatch($newRequest)->getContent();
}
0
Pankaj Garg