CHI SONO
{
"name": "Matteo Mangoni",
"description": "PHP e Full Stack developer con oltre 11 anni di esperienza nel settore",
"age": 31,
"skills": [ "PHP", "Laravel", "Symfony", "Vue.js", "ReactJS", "React Native", "Node.JS" ],
"company": {
"name": "EWEBITE SEO & Digital Marketing",
"url": "https://www.ewebite.it"
}
}
Ai miei tempi... jQuery era il futuro
Ai miei tempi... WordPress era un astro nascente
Flexible Laravel
come rendere meno traumatica la gestione di un sistema legacy
Il progetto
Rinnovare un applicativo senza intaccare i suoi
servizi secondari e il funzionamento della web app esistente.
WEB APP
MOBILE
DESKTOP
Il risultato desiderato
WEB APP
MOBILE
DESKTOP
NUOVA WEB APP
Laravel come risorsa.
- Facile da utilizzare
- Ottima documentazione
- Estremamente potente
- Flessibile
Convention over configuration
Paradigma di software design utilizzato (da Laravel, ma anche da Ruby on Rails) per diminuire sensibilmente il numero di scelte delegate direttamente allo sviluppatore, a patto che quest'ultimo decida di sottostare a determinate regole e rispettare un certo numero di convenzioni.
Un esempio pratico...
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
//
}
Questa singola classe, così com'è, rappresenta già di per sé un model completamente funzionante, il quale si interfaccia con il database presupponendo che esista una tabella chiamata "categories", ovvero il nome del model al plurale.
E la flessibilità?
L'utilizzo di tale paradigma non implica necessariamente l'impossibilità di avere un ambiente di sviluppo flessibile e altamente configurabile. Laravel, nello specifico, ci consente di farlo in maniera piuttosto semplice per tutti gli aspetti fondamentali della nostra applicazione.
Il punto di partenza
<?php
// ...
class CreateGroupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('gruppi_macchine', function (Blueprint $table) {
$table->increments('id');
$table->string('nomegruppo');
$table->timestamps();
});
}
// ...
}
<?php
// ...
class CreateMachineriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('macchine', function (Blueprint $table) {
$table->increments('idmacchina');
$table->unsignedInteger('id_gruppomacchine');
$table->string('nome_macchina');
$table->string('codicemacchina');
$table->string('posizione_macchina');
$table->timestamps();
});
}
// ...
}
Quando è strettamente necessario, non abbiate paura di andare contro le convenzioni. Fate il possibile per rendere l’ambiente di sviluppo il migliore possibile per il vostro scopo.
Mappare le tabelle con dei model dedicati, creando relazioni volte a semplificare la gestione del contenuto.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Group extends Model
{
protected $table = 'gruppi_macchine';
public function machineries()
{
return $this->hasMany('App\Machinery', 'id_gruppomacchine');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Machinery extends Model
{
protected $table = 'macchine';
protected $primaryKey = 'idmacchina';
public function maintenance()
{
return $this->hasOne('App\MaintenanceSheet', 'macchina_id', 'idmacchina');
}
}
Se i campi del database hanno nomi inconsistenti e poveri di rigore logico, provate a creare voi stessi una regola univoca e seguitela sempre.
Tentativo #1: creazione di accessor per rimappare i campi più problematici. Ottima soluzione a livello di tempi di progettazione, ma scartata immediatamente perché poco efficace, troppo verbosa e lunga da implementare in ogni singolo model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Machinery extends Model
{
// ...
protected $appends = ['name'];
protected $visible = ['name'];
/**
* Get the machinery's name.
*
* @return string
*/
public function getNameAttribute()
{
return $this->nome_macchina;
}
}
// GET /machineries/1
{
"name": "Macchina #1"
}
È importante isolare le astrazioni e non sovraccaricare di responsabilità i model.
!
Utilizzare le date come istanze di Carbon
{
"id": 1,
"macchina_id": 1,
"id_cadenza": 1,
"termine_manutenzione": "2018-12-20"
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MaintenanceSheet extends Model
{
protected $table = 'schedemanutenzione';
protected $dates = ['termine_manutenzione'];
protected $casts = ['termine_manutenzione' => 'date:d/m/Y'];
protected $dateFormat = 'Y-m-d';
}
{
"id": 1,
"macchina_id": 1,
"id_cadenza": 1,
"termine_manutenzione": "20/12/2018"
}
Astrazione tramite API resources, un modo semplice e veloce per normalizzare i dati ricevuti in output dal database.
<?php
// ...
class MachineryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->idmacchina,
'name' => $this->nome_macchina,
'code' => $this->codicemacchina,
'created_at' => $this->created_at->format('d/m/Y'),
'updated_at' => $this->updated_at->format('d/m/Y')
];
}
}
Un altro step fondamentale: scrivere test capillari sull'intero backend.
Importantissimo soprattutto in ottica di futuri sviluppi.
E poi siamo finalmente riusciti a sviluppare la nostra applicazione con Vue.JS senza problem... NO.
Proprio quando tutto sembrava andare nella direzione giusta, ci siamo trovati davanti un altro ostacolo: aggiungere nuove funzionalità, senza alterare il funzionamento delle applicazioni preesistenti.
Sviluppare un sistema che sospenda la manutenzione ricorrente senza intaccare il planner, che risiede ancora nella vecchia web app
?
Ogni tanto, per portare a casa il risultato bisogna essere creativi, giocare con i tool a nostra disposizione in maniera non convenzionale.
!
Il futuro
Cosa si può fare adesso per migliorare ulteriormente il prodotto finale?
Su cosa abbiamo dovuto sorvolare?
https://joind.in/talk/b91b5
matt.mangoni@gmail.com
LaravelDay 2018 - Flexible Laravel
By Matteo Mangoni
LaravelDay 2018 - Flexible Laravel
- 1,057