How to Create A Custom Faker for Product and Categories in Laravel
with laravel seeders and factories we can create fake records in the database to have something to show in the UI.
what if instead of fake and meaningless data we want to have records that are real or seem real so we have a better good looking UI?
in this example we are going to use the faker package but instead of using the default data that exists in the package, we will add our own data by creating a data provider and attaching it to the faker package.
Create a Product Factory
first we have to create a factory for product model.
php artisan make:factory ProductFactory
ProductFactory.php is created in database\factories folder.
before writing anything in the ProductFactory we create the provider class.
Create Custom Provider for Faker
a provider is just a php class that extends \Faker\Provider\Base
class
if you take a look at the faker package source code you’ll see a provider folder that contains all the default providers. for example there is a PhoneNumber.php that extends Faker\Provider\Base
class.
![faker-php source code](https://phpjunior.com/wp-content/uploads/2023/10/fakerphp-1024x460.jpg)
we can create a class just like this one.
we create a class in app\ProductFaker\Product.php
the folder name and route is not important just make sure to use the proper namespace and extend \Faker\Provider\Base.
namespace App\ProductFaker;
class Product extends \Faker\Provider\Base
{
}
when we use faker and call a method on it like this:
$this->faker->phoneNumber()
it looks for a phoneNumber method in all of its providers that are attatched to it.
the first method that it finds will be called. so if we create a provider and that provider has a phoneNumber method we can overwrite its functionality.
in the provider class we created, write these methods:
class Product extends \Faker\Provider\Base
{
public function title()
{
}
public function price()
{
}
public function description()
{
}
public function category()
{
}
public function image()
{
}
}
each of these methods has to return a value related to a product. for the product data we are going to use fake store api. it is a free api that has a few real product samples for using instead of “lorem ipusum” or random numbers.
we have to request an endpoint and we will get a json response of a product.
I create a private method in the provider class to get the product from the api and then use the response in other methods:
use Illuminate\Support\Facades\Http;
class Product extends \Faker\Provider\Base
{
//...
private function getProduct()
{
$randomId = random_int(1, 20);
$response = Http::get('https://fakestoreapi.com/products/' . $randomId);
return $response->json();
}
}
Fake Store Api has 20 products.
IDs range from 1 to 20 so we can use that to get each product.
we use Http Facade in laravel to request the endpoint and recieve the product. since we want a different product every time, we generate a random id from 1 to 20 and use that random ID in the endpoint and finally return the response.
the api returns a a json like this:
{
"id": 1,
"title": "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops",
"price": 109.95,
"description": "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday",
"category": "men's clothing",
"image": "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",
"rating": {
"rate": 3.9,
"count": 120
}
}
then we use the response in the methods we created:
namespace App\ProductFaker;
class Product extends \Faker\Provider\Base
{
public function title()
{
return ($this->getProduct())['title'];
}
public function price()
{
return ($this->getProduct())['price'];
}
public function description()
{
return ($this->getProduct())['description'];
}
public function category()
{
return ($this->getProduct())['category'];
}
public function image()
{
return ($this->getProduct())['image'];
}
private function getProduct()
{
$randomId = random_int(1, 20);
$response = Http::get('https://fakestoreapi.com/products/' . $randomId);
return $response->json();
}
}
in each method we get the value for each index from the response.
Attach the Provider to Faker
the custom provider is ready. now it’s time to make fakerphp package to use our class as its provider.
in the ProductFactory class we created in the beginning, use the addProvider()
method to attach the provider.
//ProductFactory.php
use App\ProductFaker\Product;
public function definition()
{
$this->faker->addProvider(new Product($this->faker));
return [
'title' => $this->faker->title(),
'price' => $this->faker->price(),
'description' => $this->faker->description(),
'category' => $this->faker->category(),
'image' => $this->faker->image(),
];
}
in the addProvider
method instantiate an object from the Product provider class and pass $this->faker
as an argument to it.
after attaching the provider in the ProductFactory, we can use the methods of the custom provider.
if you haven’t created the seeder run:
php artisan make:seeder ProductSeeder
obviously you also should have the migration file.
php artisan make:migration create_products_table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->decimal('price');
$table->text('description');
$table->string('category');
$table->string('image');
$table->timestamps();
});
}
php artisan migrate
use the factory in ProductSeeder:
//ProductSeeder.php
use App\Models\Product;
public function run()
{
Product::factory()->count(20)->create();
}
then run:
php artisan db:seed --class=ProductSeeder
and finally the products are inserted in the databse
![inserted products from custom factory created by fake store api](https://phpjunior.com/wp-content/uploads/2023/10/image-9-1024x525.png)
fakerphp documentation has mentioned a few examples of custom providers as third-party packages that you can use in your projects.