W programowaniu często spotykanym problemem jest próba znalezienia złotego środka pomiędzy tworzeniem aplikacji monolitycznej, a aplikacji zbudowanej z modułow czy też mikroserwisów. W Laravelu, gdzieś pomiędzy tymi wyborami, leży mozliwość tworzenia własnych pakietów, czyli odrębnych jednostek kodu, które mogą być użyte w innych projektach. Taka potrzeba nie jest rzadkością – na pewno każdy z nas szybko znalazłby funkcjonalności, które chociaż raz zdublowały się w dwóch i więcej projektach. Przejdźmy do konkretów.
W dzisiejszym wpisie postaramy się stworzyć podstawowy pakiet, który to będzie wyświetlał imię pobrane z parametru adresu URL. Od czego zaczynamy?
Na początek stwórzmy strukturę katalogów:
- packages/<autor>/<nazwaPakietu>
- packages/<autor>/<nazwaPakietu>/src
gdzie <autor> to oczywiście autor pakietu, czy też organizacja, natomiast <nazwaPakietu> to nazwa. Całą tą strukturę umieszczamy w katalogu głównym aplikacji (na tym samym poziomie, co katalog app). Jak łatwo się domyśleć, podkatalog src będzie zawierał źródła naszego pakietu.
Idąc dalej, przejdźmy do głównego katalogu aplikacji i zmodyfikujmy główny composer.json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "require": { "php": ">=7.0.0", }, "autoload": { "classmap": [ "database", ], "psr-4": { "App\\": "app/", "Kaminski\\Imiona\\": "packages/kaminski/imiona/src/" } } } |
Tu właściwie dodajemy do naszego autoloadera nowy pakiet i podajemy jego źródła. Na koniec uruchamiamy composer dump-autoload i przechodzimy do tworzenia samego kodu naszego pakietu.
Zaczynamy od stworzenia pliku packages/kaminski/imiona/src/KaminskiImionaProvider.php Plik ten będzie miejscem startowym naszego pakietu. W metodzie register() dołączamy jeszczenie stworzony plik z routingiem naszego pakietu (zauważmy, iż pakiet będzie miał osobny plik routingu!), a także tworzymy kontroler Imie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace Kaminski\Imiona; use Illuminate\Support\ServiceProvider; class KaminskiImionaProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { // } /** * Register the application services. * * @return void */ public function register() { include __DIR__.'/routes/web.php'; $this->app->make('Kaminski\Imiona\ImionaController'); } } |
Mając już Service Provider możemy go zarejestrować dodając w pliku config/app.php:
1 2 3 4 5 6 7 |
'providers' => [ /* * Laravel Framework Service Providers... */ .... Kaminski\Imiona\KaminskiImionaProvider::class ], |
Rejestracja package’u jest już zakończona, przejdźmy do brakującego kontrolera i routingu:
Plik packages/kaminski/imiona/ImieController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php namespace Kaminski/Imiona; use App\Http\Controllers\Controller; use Carbon\Carbon; class ImionaController extends Controller { public function index($imie) { echo $imie; } } |
Tworzymy tez plik routingu:
packages/kaminski/imiona/src/routers/web.php
1 2 3 |
<?php Route::get('imiona/{imie}','Kaminski\Imiona\ImionaController@index'); |
Struktura stworzonego pakietu powinna przedstawiac się następująco: Tak więc powinna wygladac struktura katalogów naszego pakietu:
Samo uruchomienie projektu i wywołanie odpowiedniego routingu zaowocuje:
Czyli oznacza to, iż nasz projekt działa 🙂
Czas podsumowań. Ustalmy pewne fakty, mianowicie tworzenie nowego pakietu ograniczyło się do:
- utworzenia katalogu packages/<vendor>/<packageName> z routingiem, kontolerem i Providerem
- zmiany linii w pliku config/app.php (dodanie Providera)
- zmiany w głównym pliku composer.json (dodanie w PSR-4/autoload katalogu packages)
- dump autoload przez composera
Prawda, że niewiele? Może czasem warto zastanowić się, czy coś, co właśnie piszemy, nie przyda nam się przy okazji innych projektów? Może warto stworzyć osobny pakiet i choć trochę rozbić monolityczność projektowanej aplikacji?