Skip to main content

Development Guide

Development workflow, best practices, and common tasks for ZÈYA API.

Development Workflow

1. Create Feature Branch

git checkout -b feature/your-feature-name

2. Make Changes

Follow Laravel conventions and coding standards (see Contributing).

3. Write Tests

# Create test file
php artisan make:test ProductTest

# Run tests
php artisan test --filter ProductTest

4. Format Code

# Format code with Laravel Pint
php artisan pint

# Check without fixing
php artisan pint --test

5. Commit Changes

git add .
git commit -m "feat: add product search feature"

6. Push and Create PR

git push origin feature/your-feature-name

Code Quality

Laravel Pint

Laravel Pint is used for code formatting:

# Format all files
php artisan pint

# Format specific file
php artisan pint app/Http/Controllers/ProductController.php

# Check without fixing
php artisan pint --test

PHPUnit Testing

# Run all tests
php artisan test

# Run specific test file
php artisan test --filter ProductTest

# Run with coverage
php artisan test --coverage

# Run specific test method
php artisan test --filter test_can_create_product

Common Development Tasks

Creating a New Feature

  1. Create Migration
php artisan make:migration create_products_table
  1. Create Model
php artisan make:model Product -m
  1. Create Controller
php artisan make:controller ProductController --api --resource
  1. Create Form Request
php artisan make:request StoreProductRequest
php artisan make:request UpdateProductRequest
  1. Create API Resource
php artisan make:resource ProductResource
  1. Create Service
# Manual creation in app/Services/ProductService.php
  1. Add Routes
// routes/api.php
Route::apiResource('products', ProductController::class);
  1. Write Tests
php artisan make:test ProductTest

Database Operations

# Run migrations
php artisan migrate

# Rollback last migration
php artisan migrate:rollback

# Rollback all migrations
php artisan migrate:reset

# Fresh migration with seeding
php artisan migrate:fresh --seed

# Create migration
php artisan make:migration add_column_to_products_table

# Create seeder
php artisan make:seeder ProductSeeder

# Run seeder
php artisan db:seed --class=ProductSeeder

Queue Development

# Run queue worker
php artisan queue:work

# Run specific queue
php artisan queue:work --queue=high,default

# Run with specific connection
php artisan queue:work redis

# Restart workers after code changes
php artisan queue:restart

# View failed jobs
php artisan queue:failed

# Retry failed job
php artisan queue:retry {job-id}

# Clear failed jobs
php artisan queue:flush

Cache Management

# Clear all caches
php artisan optimize:clear

# Cache configuration
php artisan config:cache

# Clear config cache
php artisan config:clear

# Cache routes
php artisan route:cache

# Clear route cache
php artisan route:clear

# Cache views
php artisan view:cache

# Clear view cache
php artisan view:clear

# Clear specific cache
php artisan cache:clear

Logging

# View logs
tail -f storage/logs/laravel.log

# Clear logs (be careful!)
> storage/logs/laravel.log

Debugging

Tinker

Laravel Tinker for interactive debugging:

php artisan tinker

# Example usage
>>> $user = User::find(1);
>>> $user->products;

Debugging Tools

  • Laravel Debugbar (if installed)
  • dd() - Dump and die
  • dump() - Dump without dying
  • Log::debug() - Log to file

Common Debugging Commands

# Check routes
php artisan route:list

# Check config
php artisan config:show database

# Check environment
php artisan env

# Clear everything
php artisan optimize:clear

Local Development Setup

Environment Variables

Use .env for local development:

APP_ENV=local
APP_DEBUG=true

Database Seeding

# Seed database
php artisan db:seed

# Seed specific seeder
php artisan db:seed --class=UserSeeder

Mail Testing

Use Mailtrap or similar for local mail testing:

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password

Best Practices

1. Use Form Requests

Always use Form Requests for validation:

// ✅ Good
public function store(StoreProductRequest $request)
{
$validated = $request->validated();
// ...
}

// ❌ Bad
public function store(Request $request)
{
$request->validate([
'title' => 'required',
]);
// ...
}

2. Use Services for Business Logic

Keep controllers thin:

// ✅ Good
public function store(StoreProductRequest $request, ProductService $service)
{
$product = $service->createProduct($request->validated(), $request->user());
return new ProductResource($product);
}

// ❌ Bad
public function store(StoreProductRequest $request)
{
// 50 lines of business logic here
}

3. Use API Resources

Transform responses consistently:

// ✅ Good
return new ProductResource($product);

// ❌ Bad
return response()->json([
'id' => $product->id,
'title' => $product->title,
// ...
]);

4. Eager Load Relationships

Prevent N+1 queries:

// ✅ Good
$products = Product::with(['owner', 'category', 'images'])->get();

// ❌ Bad
$products = Product::all();
foreach ($products as $product) {
$product->owner; // N+1 query!
}

5. Use Transactions

For multiple database operations:

DB::transaction(function () use ($data) {
$product = Product::create($data);
$product->images()->createMany($imageData);
});