cbaconnier/php-api-factory

A fluent PHP library for generating fake API response data

Installs: 50

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/cbaconnier/php-api-factory

1.0.1 2025-10-15 11:17 UTC

This package is auto-updated.

Last update: 2025-11-15 11:31:19 UTC


README

A fluent PHP library for generating fake API response data. Perfect for testing and creating mock API responses.

Inspired by Laravel's Eloquent Factories.

Installation

composer require --dev cbaconnier/php-api-factory

Basic Usage

Create a factory by extending ApiFactory and defining your data structure:

use Cbaconnier\PhpApiFactory\ApiFactory;

class UserApiFactory extends ApiFactory
{
    // optional
    protected ?string $wrapper = 'users';

    protected function definition(): array
    {
        return [
            'id' => $this->faker->unique()->randomNumber(8),
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->email(),
            'role' => $this->faker->randomElement(['admin', 'member', 'viewer']),
            'created_at' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
        ];
    }
}

Generate data:

// Single item
$user = UserApiFactory::new()->make();
// ['id' => 12345678, 'name' => 'John Doe', ...]

// Multiple items
$users = UserApiFactory::new()->count(5)->make();
// [['id' => 1, ...], ['id' => 2, ...], ...]

// Wrapped response
$response = UserApiFactory::new()->count(5)->wrap()->make();
// ['users' => [['id' => 1, ...], ['id' => 2, ...]]]

Features

Override Attributes

$user = UserApiFactory::new()->make(['name' => 'Jane Doe', 'role' => 'admin']);

States

Define reusable modifications:

class UserApiFactory extends ApiFactory
{
    public function admin(): static
    {
        return $this->state(['role' => 'admin']);
    }

    public function suspended(): static
    {
        return $this->state([
            'status' => 'suspended',
            'suspended_at' => $this->faker->dateTime()->format('Y-m-d H:i:s'),
        ]);
    }
}

$admin = UserApiFactory::new()->admin()->make();
$suspendedAdmin = UserApiFactory::new()->admin()->suspended()->make();

Sequences

Generate unique values for each item:

$users = UserApiFactory::new()
    ->count(3)
    ->sequence(fn($index) => ['name' => "User {$index}"])
    ->make();
// [['name' => 'User 0', ...], ['name' => 'User 1', ...], ...]

// Cycle through values
$users = UserApiFactory::new()
    ->count(4)
    ->sequence([
        ['role' => 'admin'],
        ['role' => 'member'],
        ['role' => 'viewer'],
    ])
    ->make();
// Roles: admin, member, viewer, admin

Field Filtering

// Only specific fields
$user = UserApiFactory::new()->only(['id', 'name'])->make();

// Exclude specific fields
$user = UserApiFactory::new()->except(['email', 'created_at'])->make();

Recycle Data

Reuse data from existing collections:

$projects = [['id' => 1], ['id' => 2]];

$tasks = TaskFactory::new()
    ->count(10)
    ->recycle($projects, 'project_id')
    ->make();
// Each task gets a random project_id (1 or 2)

// With custom source key
$users = [['user_id' => 100], ['user_id' => 200]];
TaskFactory::new()
    ->recycle($users, 'assigned_to', 'user_id')
    ->make();

// With callable for complex relationships
TaskFactory::new()
    ->recycle($projects, fn($project) => [
        'project' => [
            'id' => $project['id'],
            'name' => $project['name']
        ]
    ])
    ->make();

Nested Factories

Create complex nested structures:

$project = ProjectFactory::new()
    ->has('owner', UserApiFactory::new())
    ->has('tasks', TaskFactory::new()->count(5))
    ->make();
// {
//   'id': 1,
//   'name': 'Project Alpha',
//   'owner': {'id': 1, 'name': 'John Doe', ...},
//   'tasks': [{'id': 1, ...}, {'id': 2, ...}, ...]
// }

// Deep nesting
ProjectFactory::new()
    ->has('tasks', 
        TaskFactory::new()
            ->count(3)
            ->has('assignee', UserApiFactory::new())
    )
    ->make();

Metadata

Add pagination or other metadata:

ApiFactory::register('default', [
    'metadata' => fn($items) => [
        'pagination' => [
            'total' => count($items),
            'per_page' => 15,
            'current_page' => 1,
        ],
        'meta' => [
          'version' => '1.0',
        ],
    ],
]);
ApiFactory::default('default');

$response = UserApiFactory::new()
    ->count(25)
    ->wrap()
    ->withMetadata()
    ->make();
// {
//   'users': [...],
//   'pagination': {...},
//   'meta': {...},
// }

Configuration

Configure global settings:

use Cbaconnier\PhpApiFactory\ApiFactory;

ApiFactory::register('default', [
    'faker' => [
        'locale' => 'fr_FR',
        'providers' => [CustomProvider::class],
    ],
    'wrapper' => 'data',
    'metadata' => [
        'meta' => ['version' => '1.0'],
    ],
]);

ApiFactory::default('default');

Combining Features

All features work together:

$response = UserApiFactory::new()
    ->count(10)
    ->sequence(fn($i) => ['name' => "User {$i}"])
    ->admin()
    ->only(['id', 'name', 'role'])
    ->wrap()
    ->make();

Running tests

composer install
composer test

License

MIT