Skip to content

Instantly share code, notes, and snippets.

@emsifa
Last active August 29, 2015 14:24
Show Gist options
  • Save emsifa/19dc35de209a6e99520b to your computer and use it in GitHub Desktop.
Save emsifa/19dc35de209a6e99520b to your computer and use it in GitHub Desktop.
Style Ngoding gw di Laravel

Style Ngoding gw di Laravel

Sekedar berbagi, ini style ngoding di Laravel. Sebenernya nggak selalu begini, kalo lagi buru-buru ya reflek sejadinya aja. Tapi ya beginilah versi yang menurut gw 'rapih'. :p

Kenapa gw nulis beginian? supaya kalo gw kolaborasi sama orang lain main Laravel dan mereka belum 'menjelaskan' standar style ngoding mereka, gw tinggal ngasih standar style ngoding gw. Jadi mereka yang ngikutin style gw, bukan gw ngikutin style mereka... :p

Tapi tenang aja, gw yakin style ngoding gw ini cukup bagus dan rapih kok..

Controller

Controller 'rapih' versi gw tuh begini:

  • Semua method HARUS ada deskripsinya, letaknya di paling atas DocComment.
  • Method yang mewakili action dari route, gw kasih DocComment @route [METHOD] [PATH]. Biar nggak bolak balik file routes, dan biar gw tau kalo method itu action dari route.
  • Kalo route itu punya name atau as, gw kasih DocComment @name [ROUTE NAME]. Sama, biar nggak bolak-balik file routes.
  • Kalo route itu punya parameter condition, di @param taruh regexnya. Biar nggak bolak-balik file routes juga.
  • Method yang berfungsi untuk menampilkan halaman, prefix(awalan) nama methodnya itu page. Misal pageAbout, pageDetailProduct, dsb. Kadang pakai prefix form untuk mengindikasikan kalau action dari route itu ngirim halaman web berupa form. Yang ini biar orang frontend tau kalo route itu nge-return halaman web tanpa mesti liat file Controller yang memusingkan (cukup dari file routes). Liat juga bagian Routing, alasan gw point 2.
  • Method yang berfungsi untuk mengirim JSON, prefix methodnya itu json. Misal jsonDetailProduct, jsonSearchProduct, dsb. Yang ini juga biar orang frontend tau kalo route itu nge-return json tanpa mesti liat file Controller.
  • Method yang nggak mewakili action dari route, kasih visibility protected, kecuali itu static method dimana ada yang gunain method itu di luar class.
  • Selebihnya liat PSR-2

Model

Model 'rapih' versi gw tuh begini:

  • Usahain PSR-2.
  • Method dikelompokin (pake DocComment, tapi pake '|', bukan '*', biar highlightnya beda di editor :v), biasanya jadi 4 bagian:
    • MODEL HELPERS: Isinya method-method yang akan digunain sebagai helper(penyederhana lah) dari object model itu.
    • STATIC HELPERS: Sama kayak model helpers, cuma method-method ini static.
    • QUERY SCOPES: Ini isinya method-method scope.
    • MODEL RELATIONS: Ini isinya method-method yang ngehubungin ke model lain.
    • ATTRIBUTE ACCESSORS: Ini jarang, isinya method-method accessors.
    • ATTRIBUTE MUTATORS: Jarang juga, isinya method-method mutators.
    • Selebihnya bisa kelompok PROTECTED, PRIVATE, dsb sesuai kebutuhan.

Routing

Beberapa web developer anti-Laravel ada yg berpendapat males pake Laravel karena males ngedaftarin routes secara manual. Tapi gw pribadi nganggep Routing itu emang seharusnya begitu, gw pun sangat menyarankan yang biasa pake CI untuk ngedaftarin routesnya di config/routes.php, dan ini alesan (pribadi gw):

  1. Gw nganggep routing itu jembatan antara backend developer dan frontend developer. Jadi kalo orang frontend mau liat-liat path dari Route untuk keperluan AJAX (misal), mereka cukup liat file routes.php, mereka nggak perlu ngubek2 source Controller. Karena itu bukan areanya mereka.
  2. Kita bisa dapet 'gambaran' keseluruhan aplikasi kita cukup dari file routes.php. Kalo suatu saat maintenance kita lupa aplikasi kita isinya apaan aja, kita nggak perlu ngubek2 source file-file controller. Kalo aplikasi kecil2an sih gpp, tapi kalo aplikasi mulai kompleks, ngubek2 file controller? males~
  3. Kalo yg ini bukan alesan kenapa routing mesti manual sih, tapi gw suka Routing ala Laravel, lumen, slim, dsb itu mereka bisa grouping, apalagi ada middleware. Ini bikin route jadi lebih mudah di organisir.

Jadi berdasarkan alasan2 itu, untuk routing gw lebih suka begini:

  • Sebisa mungkin, saat production nggak ada Route::resource atau Route::controller. Liat alasan gw point 1 dan 2.
  • Route di group berdasarkan module. Biasanya gw gunain Route::group itu untuk grouping module, jadi group itu punya prefix module itu, misal module artikel, punya 'prefix' => 'artikel'. Kalo di modul admin ada submodul artikel, ya group artikel ada di dalam group admin (nested group: admin > artikel).
  • Semua route punya nama (as). Ini biar kalo suatu saat client protes "ini url(path)nya bisa di ganti nggak? kurang enak dibacanya soalnya...", sementara path dari route itu kita pake di 10 file (misal untuk keperluan link, form action, dsb). Kalo kasusnya begitu kita mesti ubek2 dan edit 1-1 tuh file. Sementara kalo route dikasih nama, kita cukup ubah path dari route itu, untuk url di form action, link, dsb pakai fungsi route('nama_route'). Jadi nanti kalo diubah path routenya, otomatis mereka nyesuain.
  • Route nggak perlu dikasih DocComment kayak method di Controller. Kasih 1-2 baris sih gpp, kalo kebanyakan nanti malah ribet bacanya. Kalo di method controller dikasih DocComment cukup banyak karena controller isinya business logic (baca: kodingnya ribet disana). Tapi kalo di file routes kan isinya cuma ngedaftarin routes. Kalo dikasih komentar berlebihan di setiap route malah ngeribetin komentarnya. Lagipula di style controller gw, gw ngasih prefix page, form, json, post, dsb. Jadi bagian action atau uses di route udah cukup menjelaskan Route itu tujuannya apa.
  • Kalo group isinya routenya banyak, di penutup group kasih baris komentar.
  • Path dari route selalu diawalin / dan jangan diakhirin dengan /. Misal /(untuk index), /article, /u/{username}, dsb. Soalnya ada beberapa framework yg ngeharusin path diawalin / (misal Slim), jadi biar kalo gw gunain framework lain, gw udah terbiasa, nggak mesti nambah2 adapt list lagi :p
<?php
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
class ContohController extends Controller
{
/**
* Halaman form edit produk
*
* @route GET /admin/product/edit/{id}
* @name page-edit-product
* -----------------------------------------------------------
* @param string $id /\d+/ id produk
* @return Response halaman form edit produk
*/
public function pageEditProduct($id)
{
$data['produk'] = Product::findOrFail($id);
return view('admin.pages.product.edit', $data);
}
/**
* Aksi POST edit produk
*
* @route POST /admin/product/edit/{id}
* @name post-edit-product
* -----------------------------------------------------------
* @param string $id /\d+/ id produk
* @param App\Http\Requests\Product\EditProductRequest $request
* @return Redirect ke @page-edit-product
*/
public function postEditProduct($id, EditProductRequest $request)
{
$produk = Product:findOrFail($id);
$produk->update($request->all());
return redirect()
->route('page-edit-product', [$produk->id])
->with('info', 'Data produk berhasil di edit');
}
/**
* JSON list produk untuk datatable di admin
*
* @route GET /admin/products/datatable
* @name json-datatable-list-products
* -----------------------------------------------------------
* @param Illuminate\Http\Request $request
* @return array list produk
*/
public function jsonDatatableProduct(Request $request)
{
return Product::datatable($request, ['id', 'name', 'thumb', 'created_at'], [
'<input type="checkbox" name="check" value="{{ $id }}"/>',
'<img src="{{ $row->urlThumb() }}"/>',
'{{ $row->name }}',
'{{ $row->created_at->format("d M, Y") }}'
]);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContohModel extends Model
{
protected $table = 'contoh_model';
public $fillable = ['name', 'description', 'published', 'user_id', 'etc'];
/**
| --------------------------------------------------------------------
| MODEL HELPERS
| --------------------------------------------------------------------
| Dibawah ini method-method yang berfungsi sebagai helper dari model object
| blah blah blah...
*/
/**
* Publish contoh
*
* @return boolean
*/
public function publish()
{
return $this->update(['published' => 1]);
}
/**
| --------------------------------------------------------------------
| STATIC HELPERS
| --------------------------------------------------------------------
| Dibawah ini method-method yang berfungsi sebagai static helpers
| blah blah blah...
*/
/**
* Find record by name
*
* @param string $name
* @return null|App\ContohModel
*/
public static function findByName($name)
{
return static::where("name", $name)->first();
}
/**
| --------------------------------------------------------------------
| QUERY SCOPES
| --------------------------------------------------------------------
| Scope-scope dari model
| blah blah blah...
*/
/**
* Scope published
*
* @param QueryBuilder $query
* @return QueryBuilder
*/
public function scopePublished($query)
{
return $query->where('published', 1);
}
/**
| --------------------------------------------------------------------
| MODEL RELATIONS
| --------------------------------------------------------------------
| Method-method yang berfungsi sebagai penghubung/relasi ke model lain
| blah blah blah...
*/
/**
* Relasi ke App\User
*
* @return QueryBuilder
*/
public function user()
{
return $this->hasOne(User::class);
}
}
<?php
Route::get('/', [
'as' => 'page-index',
'uses' => 'FrontController@pageIndex'
]);
// # MODUL ARTIKEL
Route::group(['prefix' => 'artikel'], function() {
Route::get('/{page}', [
'as' => 'page-list-artikel',
'uses' => 'ArticleController@pageList'
])->where('page', '[0-9]+');
Route::get('/read/{url_title}', [
'as' => 'page-read-artikel',
'uses' => 'ArticleController@pageRead'
]);
Route::post('/rate', [
'as' => 'post-rate-artikel',
'uses' => 'ArticleController@postRate'
]);
});
// # MODUL ADMIN
Route::group(['prefix' => 'admin', 'middleware' => 'auth', 'namespace' => 'Admin'], function() {
// ## MODUL ADMIN/ARTIKEL
Route::group(['prefix' => 'artikel'], function() {
Route::get('/', [
'as' => 'admin-page-list-artikel',
'uses' => 'ArticleController@pageList'
]);
Route::get('/datatable', [
'as' => 'admin-datatable-list-artikel',
'uses' => 'ArticleController@jsonDatatable'
]);
Route::get('/create', [
'as' => 'admin-page-create-artikel',
'uses' => 'ArticleController@pageCreate'
]);
Route::post('/create', [
'as' => 'admin-post-create-artikel',
'uses' => 'ArticleController@postCreate'
]);
}); //endgroup: MODUL ADMIN/ARTIKEL
}); //endgroup: MODUL ADMIN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment