PHP code example of coagus / php-api-builder

1. Go to this page and download the library: Download coagus/php-api-builder library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

coagus / php-api-builder example snippets


#[Table('products')]
#[SoftDelete]
class Product extends Entity
{
    #[PrimaryKey]
    public private(set) int $id;

    #[Required, MaxLength(100)]
    public string $name { set => trim($value); }

    #[Required]
    public float $price {
        set {
            if ($value < 0) throw new \InvalidArgumentException('Price must be positive');
            $this->price = round($value, 2);
        }
    }

    #[Required, Email, Unique]
    public string $email { set => strtolower(trim($value)); }

    #[Hidden]
    public string $passwordHash = '';

    #[Ignore]
    public string $password {
        set => $this->passwordHash = password_hash($value, PASSWORD_ARGON2ID);
    }

    #[BelongsTo(Category::class)]
    public int $categoryId;

    #[HasMany(Review::class)]
    public array $reviews;
}


namespace App\Entities;

use Coagus\PhpApiBuilder\ORM\Entity;
use Coagus\PhpApiBuilder\Attributes\{Table, PrimaryKey, SoftDelete};
use Coagus\PhpApiBuilder\Validation\Attributes\{Required};

#[Table('users')]
#[SoftDelete]
class User extends Entity
{
    #[PrimaryKey]
    public private(set) int $id;

    #[Required]
    public string $name { set => trim($value); }

    #[Required]
    public string $email;

    #[Required]
    public string $password;
}

#[PublicResource]
#[Route('health')]
class Health extends Service
{
    public function get(): void
    {
        $this->success([
            'status' => 'healthy',
            'timestamp' => date('c'),
        ]);
    }
}

use Coagus\PhpApiBuilder\API;
use App\Services\Jwk;
use App\Services\OpenIdConfig;

$api = new API(
    namespace: 'App\\Services',
    apiPrefix: '/api/v1',
    wellKnown: [
        '/.well-known/jwks.json'             => [Jwk::class, 'get'],
        '/.well-known/openid-configuration'  => [OpenIdConfig::class, 'get'],
    ]
);

$api->run()->send();

class UserService extends APIDB
{
    protected string $entity = User::class;

    // CRUD works automatically: GET, POST, PUT, PATCH, DELETE

    // Custom: POST /api/v1/users/login
    public function postLogin(): void
    {
        $input = $this->getInput();
        $user = User::query()->where('email', $input->email)->first();

        if (!$user || !password_verify($input->password, $user->password)) {
            $this->error('Invalid credentials', 401);
            return;
        }

        $this->success(['token' => Auth::generateAccessToken($user->toArray())]);
    }
}

use Coagus\PhpApiBuilder\Attributes\Middleware;
use Coagus\PhpApiBuilder\Http\Middleware\RateLimitMiddleware;
use Coagus\PhpApiBuilder\Http\Middleware\AuthMiddleware;

class Reports extends APIDB
{
    protected string $entity = Report::class;

    // Tight per-endpoint budget, independent of the global stack.
    #[Middleware(RateLimitMiddleware::class, limit: 10, windowSeconds: 60)]
    public function get(): void
    {
        // ...
    }

    // Multiple middlewares stack in declaration order.
    #[Middleware(AuthMiddleware::class)]
    #[Middleware(RateLimitMiddleware::class, limit: 3, windowSeconds: 60)]
    public function postExport(): void
    {
        // ...
    }
}

#[Hidden]
public string $passwordHash = '';

#[Ignore]
public string $password {
    set => $this->passwordHash = password_hash($value, PASSWORD_ARGON2ID);
}

// Level 1: Shortcuts
$user = User::find(1);
$users = User::all();

// Level 2: Fluent
$users = User::query()
    ->where('active', true)
    ->orderBy('created_at', 'desc')
    ->limit(10)
    ->get();

// Level 3: Eager loading (no N+1 queries)
$users = User::query()
    ->with('orders', 'orders.items')
    ->where('active', true)
    ->get();

// Level 4: Reusable scopes
$users = User::query()->active()->recent(7)->get();

// Level 5: Raw SQL (always parameterized)
$results = Connection::getInstance()->query(
    'SELECT u.*, COUNT(o.id) as total FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id HAVING total > ?',
    [5]
);

#[Table('users')]
class User extends Entity
{
    #[Required, MaxLength(50)]
    public string $name { set => trim($value); }

    #[Required, Email, Unique]
    public string $email { set => strtolower(trim($value)); }

    #[Hidden]
    public string $passwordHash = '';

    #[Ignore]
    public string $password {
        set => $this->passwordHash = password_hash($value, PASSWORD_ARGON2ID);
    }
}

use Coagus\PhpApiBuilder\ORM\Connection;

Connection::configure([
    'dsn' => $_ENV['DATABASE_URL'] ?? 'postgresql://alice:[email protected]:6543/postgres',
]);
bash
> docker compose exec app bash
> php vendor/bin/api make:entity Product
> 

my-api/
├── api                     # CLI wrapper (auto-detects PHP vs Docker)
├── .env                    # Configuration
├── index.php               # Entry point
├── entities/               # Database entities (auto CRUD)
│   ├── User.php
│   └── Product.php
├── services/               # Pure services (no DB)
│   ├── Health.php
│   └── AuthMiddleware.php   # Custom middleware (also in services/)
├── tests/                  # Pest tests
├── docker-compose.yml      # Docker environment
└── log/                    # Error logs (auto-generated)
bash
composer