Skip to content

Instantly share code, notes, and snippets.

@lam0819
Last active February 9, 2026 03:01
Show Gist options
  • Select an option

  • Save lam0819/43a4d0f606ee154311752180686bea93 to your computer and use it in GitHub Desktop.

Select an option

Save lam0819/43a4d0f606ee154311752180686bea93 to your computer and use it in GitHub Desktop.
TAYLOR-Principles.md

Taylor Otwell Methodology — Coding Principles

Every line of code in this project MUST follow these principles:

1. Elegant & Expressive Code

// YES — reads like English
$page = Page::with('blocks')->published()->findOrFail($id);

// NO — verbose, mechanical
$page = Page::where('status', '=', 'published')
    ->where('id', '=', $id)
    ->with(['blocks'])
    ->firstOrFail();
  • Use Eloquent scopes for reusable query logic
  • Use accessors and mutators for data transformation
  • Use API Resources for JSON serialization — never return raw models
  • Prefer fluent interfaces and method chaining

2. Convention Over Configuration

  • Follow Laravel's default directory structure — do NOT invent custom layouts
  • Use artisan make:* generators for all scaffolding
  • Use Route Model Binding — never manually find models in controllers
  • Use Form Requests for validation — never validate in controllers
  • Use Resource Controllers with standard method names (index, store, show, update, destroy)
  • Use snake_case for database columns, camelCase for JSON API output (via Resources)

3. Thin Controllers, Fat Models

// Controller — thin, delegates everything
class PageController extends Controller
{
    public function store(StorePageRequest $request)
    {
        $page = Page::create($request->validated());

        return new PageResource($page->load('blocks'));
    }
}
  • Controllers: receive request, delegate, return response. Nothing else.
  • Models: relationships, scopes, accessors, business logic
  • Services: complex business logic that spans multiple models
  • Form Requests: validation rules and authorization
  • Resources: JSON transformation

4. Use Laravel's Built-in Features

Always prefer Laravel's built-in solutions over third-party packages:

Need Use NOT
Validation Form Requests manual validation
JSON output API Resources ->toArray()
Auth Sanctum (API) + Session (web) JWT packages
File storage Storage facade raw filesystem
Cache Cache facade manual caching
Queue jobs Laravel Queues raw process spawning
Events Laravel Events/Listeners custom pub/sub
Testing PHPUnit + Laravel TestCase external testing libs
DB queries Eloquent + Query Builder raw SQL
Rate limiting RateLimiter facade custom middleware

5. Testing as a First-Class Citizen

// Every feature gets a test. No exceptions.
test('can create a page', function () {
    $response = $this->postJson('/api/v1/pages', [
        'title' => 'Home',
        'slug' => 'home',
    ]);

    $response->assertCreated()
        ->assertJsonPath('data.title', 'Home');

    $this->assertDatabaseHas('pages', ['slug' => 'home']);
});
  • Use Pest PHP for tests (Taylor's preferred testing framework)
  • Feature tests for every API endpoint
  • Unit tests for models, services, validators
  • Use factories and seeders for test data
  • Run php artisan test before every commit

6. Database Conventions

  • Table prefix: cms_ for all tables
  • Use bigIncrements('id') for primary keys
  • Use timestamps() on all tables
  • Use json columns for flexible structured data (FieldSchema, content, meta)
  • Use enum columns sparingly — prefer string with validation
  • Use foreign key constraints with cascadeOnDelete() where appropriate
  • Migrations must be idempotent — check before altering

7. API Design (JSON:API-inspired)

// Single resource
{
    "data": {
        "id": 1,
        "title": "Home",
        "slug": "home",
        "blocks": [...]
    }
}

// Collection
{
    "data": [...],
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 45,
        "last_page": 3
    }
}

// Error
{
    "error": {
        "code": "VALIDATION_ERROR",
        "message": "Content validation failed",
        "details": [...]
    }
}
  • All responses wrapped in data key
  • Pagination metadata in meta key
  • Consistent error format with error codes
  • Use HTTP status codes correctly (201 Created, 204 No Content, 422 Validation Error)

8. Code Style

  • PSR-12 coding standard
  • Strict types declaration in every PHP file: declare(strict_types=1);
  • Use PHP 8.4 features: readonly properties, enums, match expressions, named arguments, first-class callables
  • Use constructor property promotion
  • Short closures (fn()) where appropriate
  • No unnecessary comments — code should be self-documenting
  • PHPDoc only for complex return types or when adding context beyond the type system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment