Lumen

Lumen

Lumen est un nouveau framework léger qui est en fait un Laravel 5 qui a subi une bonne cure d’amaigrissement. Il rentre en concurrence avec les micro-frameworks comme slim ou silex.  On trouve donc dans Lumen des composants de Laravel mais pas tous. Cet article a pour but de faire le point de ce nouveau venu et de l’illustrer à travers une application qui est en fait une réécriture de celle que j’avais faite pour Laravel et pour laquelle j’ai écrit quelques articles. J’ai pu ainsi faire concrètement le point des différences.

img04

Pour quels usages ?

Lumen a pour objectif d’être léger est rapide, mais c’est au prix de l’abandon de nombreuses fonctionnalités. Par exemple les sessions ne sont pas activées par défaut, de même que Eloquent. Mais il demeure évidemment possible d’ajouter tout ce dont on a besoin, soit en activant un composant juste en dé-commentant du code, soit en chargeant un nouveau composant.

Lumen est plutôt destiné à la création de petits services qui ne trouveraient pas dans Laravel une réponse adaptée. On a parfois besoin de ces petits services rapides. D’autre part lorsqu’on crée une application SPA (Single Page Application) on a surtout besoin d’APIs rapides pour lesquelles Lumen semble parfait.

Installation

Lumen a besoin de :

  • PHP >= 5.4
  • Mcrypt PHP Extension
  • OpenSSL PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension

 

L’installation est simple et peut s’effectuer de deux façons :

  • Avec l’installeur :

Il faut d’abord l’installer :

composer global require "laravel/lumen-installer=~1.0"

Et ensuite créer un Lumen :

lumen new myservice
  • Avec composer :
composer create-project laravel/lumen --prefer-dist

Configuration

Contrairement à Laravel il n’y a pas de dossier config. Toutes les données de configuration se trouvent dans le fichier .env à la racine du site. A l’installation vous trouvez un fichier .env.example, faites en une copie que vous appelez .env.

Par défaut vous trouvez memcached pour les caches :

CACHE_DRIVER=memcached
SESSION_DRIVER=memcached

Si vous ne l’avez pas installé changez pour un simple cache en fichier :

CACHE_DRIVER=file
SESSION_DRIVER=file

D’autre part si vous voulez que les variables d’environnement soient reconnues il faut dé-commenter cette ligne dans bootstrap/app.php :

// Dotenv::load(__DIR__.'/../');

Vous verrez d’ailleurs un certain nombre d’éléments commentés dans ce fichier. Par exemple si vous voulez les façades vous devez dé-commenter cette ligne :

// $app->withFacades();

De même si vous voulez Eloquent :

// $app->withEloquent();

Pour mon application d’exemple j’ai aussi mis en œuvre les middlewares dans ce fichier :

$app->middleware([
	'Illuminate\Cookie\Middleware\EncryptCookies',
	'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
	'Illuminate\Session\Middleware\StartSession',
	'Illuminate\View\Middleware\ShareErrorsFromSession',
	'Laravel\Lumen\Http\Middleware\VerifyCsrfToken',
 ]);

$app->routeMiddleware([
	'auth' => 'App\Http\Middleware\Authenticate',
	'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
]);

Les routes

Le routage est simplifié par rapport à Laravel. On utilise nikic/FastRoute. On y gagne en rapidité et évidemment on y perd en possibilités.

Le routage de mon application avec Laravel se résume à :

Route::get('/', function(){
    return view('index');
});

Route::controllers([
    'auth' => 'Auth\AuthController',
    'password' => 'Auth\PasswordController',
]);

Route::resource('dream', 'DreamController', ['only' => ['index', 'store', 'update', 'destroy']]);

Avec Lumen je suis obligé de tout détailler :

$app->get('/', function() {
    return view('index');
});

$app->get('auth/log', ['uses' => 'App\Http\Controllers\Auth\AuthController@getLog']);
$app->post('auth/login', ['uses' => 'App\Http\Controllers\Auth\AuthController@postLogin']);
$app->get('auth/logout', ['uses' => 'App\Http\Controllers\Auth\AuthController@getLogout']);
$app->get('auth/register', ['uses' => 'App\Http\Controllers\Auth\AuthController@getRegister']);
$app->post('auth/register', ['uses' => 'App\Http\Controllers\Auth\AuthController@postRegister']);

$app->get('password/email', ['uses' => 'App\Http\Controllers\Auth\PasswordController@getEmail']);
$app->post('password/email', ['uses' => 'App\Http\Controllers\Auth\PasswordController@postEmail']);
$app->get('password/reset/{token}', ['uses' => 'App\Http\Controllers\Auth\PasswordController@getReset']);
$app->post('password/reset', ['uses' => 'App\Http\Controllers\Auth\PasswordController@postReset']);


$app->get('dream', ['uses' => 'App\Http\Controllers\DreamController@index']);
$app->post('dream', ['uses' => 'App\Http\Controllers\DreamController@store']);
$app->put('dream/{id}', ['uses' => 'App\Http\Controllers\DreamController@update']);
$app->delete('dream/{id}', ['uses' => 'App\Http\Controllers\DreamController@destroy']);

Toutefois l’ensemble est très lisible.

L’authentification

On dispose du composant Illuminate\Auth donc toute l’intendance est présente, mais on a perdu les contrôleurs et les traits. Pour l’application j’ai donc créé les contrôleurs :

img05

On a aussi perdu le registrar de Laravel. J’ai donc tout rapatrié dans les contrôleurs (intendance des traits et validation). J’ai ajouté le fichier pour les messages pour le renouvellement du mot de passe :

img11

J’ai créé un repository pour User :

img06

Il sert juste à enregistrer les nouveau utilisateurs mais c’est plus propre comme ça.

J’ai aussi placé les vues :

img07

L’helper csrf_token() a disparu, il m’a donc fallu le remplacer par session()->getToken() pour que ça fonctionne.

J’ai aussi mis en place les middlewares :

img08

Pour l’envoi des Email pour le renouvellement du mot de passe j’ai chargé le composant illuminate/mail dans composer.json parce que par défaut Lumen n’envoie pas d’email :

"require": {
    "laravel/lumen-framework": "5.0.*",
    "vlucas/phpdotenv": "~1.0",
    "illuminate/mail": "5.0.*"
},

De cette façon toute la partie authentification se passe parfaitement.

On voit qu’il n’est pas très difficile de retrouver cette fonctionnalité même si manifestement Lumen n’a pas été pensé dans cet objectif.

Les rêves

Pour la partie de l’application qui concerne la gestion des rêves, donc celle qui est parfaitement adaptée à Lumen je n’ai eu aucun souci. J’ai directement copié modèle et repository :

img09

J’ai aussi copié le contrôleur :

img10

Là j’ai dû un peu changer le code parce qu’on n’a plus de requête de formulaire pour la validation. Je suis donc revenu à un codage plus classique :

    /**
     * Validation rules.
     *
     */
    protected $rules = [
        'content' => 'required|max:2000',
    ];

    ...

    /**
     * Update the specified resource in storage.
     *
     * @param  Illuminate\Http\Request  $request
     * @param  int  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, $this->rules);

        if ($this->dreamRepository->update($request->all(), $id)) 
        {
            return response()->json(['result' => 'success']);
        }
    }

Au final l’application fonctionne parfaitement et est plus rapide. Mais je n’ai pas fait de mesure pour estimer le gain.

Print Friendly, PDF & Email

8 commentaires

  • foxbille

    Bonjour,
    Bon, ben Lumen poursuit donc son chemin ! Malheureusement, il n’y a quasiment aucun tuto disponible et l’aide potentielle est reduite. Je butte sur une première difficulté avec les sessions, le helper session() ne doit pas exister, je récolte une erreur. La doc Lumen de l’époque laravel-Lumen 5.x mentionne un accès via l’objet Request, mais rien de tel dans la version 8.x de la doc et mes tentatives se soldent invariablement par une erreur. Comme par exemple l’utilisation de
    @if(session()->has(‘info’))
    dans une vue => Call to undefined function session()
    ou
    if ($request->session()->has(‘users’)) {
    dans un controller => Session store not set on request.
    Quelqu’un pourrait me mettre sur une piste ?
    Merci, bonne journée
    Eric

    • foxbille

      Je progresse !
      Après avoir trouvé que la gestion des sessions est fournie par Symfony\component\HttpFoundation\Session\session.php, j’ai rajouté un « use » au début du controller et $this->session = new session() dans le construct et ça
      if ($this->sesssion->has(‘user’)…
      marche !
      J’ai vu (dans config/app.php d’une appli laravel en cours de dev) qu’il y a une façade dans Illuminate\Support\Facades\Session, mais la mise en oeuvre dépasse largement mes compétences du moment.
      Est-ce que j’ai bon ? Y a mieux ? Un tuto qqpart sur la notion de façade ?
      Eric

      • bestmomo

        Salut,

        J’avoue ne pas avoir utilisé Lumen depuis longtemps. C’est un framework léger censé gérer uniquement de API, donc sans utilisation de sessions.

        Tu peux essayer ça dans le fichier bootstrap/app.php :

        $app->middleware([
        Illuminate\Cookie\Middleware\EncryptCookies::class,
        Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        Illuminate\Session\Middleware\StartSession::class,
        Illuminate\View\Middleware\ShareErrorsFromSession::class,
        ]);

        Juste avant Register Service Providers.

  • Dan

    Tout d’abord merci pour ce petit tuto!

    Cependant je pense qu’il serait utile d’y apporter quelques clarifications.
    Utilises-tu Laravel 4 ou 5? Car le 5 n’a pas de repositories par example (je ne sais pas pour le 4).
    Du coup, il serait utile pour des noobs comme moi de savoir qu’est ce que tu y met dans le repository. Pareil pour les middlewares… C’est encore très abstrait pour un débutant comme moi..Et je n’ai aucune idée de ce que tu y fais malheureusement.

    Plus généralement, je pense qu’il serait super utile de faire un tutoriel sur l’authentication avec Lumen (login, register et gestion admin des utilisateurs). Tu risques d’avoir beaucoup de vue grâce à cela tant la doc est rudimentaire à ce sujet 😉

    Quoiqu’il en soit merci! ça m’a tout de même aidé à suivre mon petit chemin vers un login parfait, même si rien ne marche encore 😛

    • bestmomo

      Bonjour,

      Cet article s’adresse plutôt à des utilisateurs de Laravel qui veulent découvrir Lumen (qui n’est pas un Laravel, 4 ou 5, mais une version épurée). C’est plus un premier état des lieux de ce nouveau framework qu’un tuto.

      D’autre part Lumen est plutôt conçu pour répondre à des besoins simples genre API. Faire fonctionner l’authentification est possible sans trop de souci comme je l’ai fait pour cette application mais de là à créer une gestion d’administration…

      Dans une approche didactique il est plus judicieux de commencer par Laravel 5. Mon cours sur OpenClassroom sera en ligne le 12 mai, en accès gratuit, et couvrira toutes les bases de Laravel 5.

      Je ne sais pas quel sera le devenir de Lumen. Il est possible qu’il reste cantonné à des tâches simples exigeant une forte réactivité, mais il est aussi possible qu’il s’enrichisse de certaines fonctionnalités et devienne finalement un concurrent de Laravel. Affaire à suivre !

      Il serait effectivement peut-être judicieux de créer quelques tutos sur Lumen.

      • Dan

        Merci pour cette réponse 😉

        Oui en effet j’ai lu que Lumen devrait plutôt être utilisé en surface de Laravel, comme une autre couche (pour une api par example). Cependant j’étais très enthousiaste à l’idée de le tester et je voulais voir ce que ça donnait dans le contexte d’un micro-site.

        Concernant l’authentification, il me semble aussi que le framework n’est pas vraiment destiné à être utilisé dans un contexte comme le mien. Cependant il est difficile de trouver plus d’info à ce sujet (pour Lumen), ce qui est relativement frustrant je dois l’admettre. Je suis donc relativement convaincu du fait que cela peut t’apporter pas mal d’audience. J’imagine moi-même le faire.. Enfin sans prétention mais ce serait une manière de documenter mes trouvailles et de faire profiter d’autres débutants comme moi 😛

        Encore merci pour ta réponse!

Laisser un commentaire