Hi there dev!
In this article, I will be assuming you have some fundamental knowledge about, i. PHP programming language ii. Laravel framework iii. MVC iv MySQL Database
So, if you check all boxes, cool, if you don't, you might want to add this to your bookmark winks.
Let get to it!
For a small sized App, you might want not really need to use repositories, querying models from your controllers is just fine, but, for larger applications, it get really cumbersome and untidy for you to do that. Likewise, testing your application becomes an headache. Hence, the need to use repositories.
Don't feel convinced enough? read some articles on the web!
So, let's say we are building a small API to fetch countries, cities and states from the database. Again, the essence of this article is for you see how you can refactor you code to use the repository pattern.
Let's create a model and migration for each of them using the command
php artisan make:model Country --migration
php artisan make:model City --migration
php artisan make:model State --migration
The above commands will generate a model and a corresponding migration file. You can now go on to seed your database with data.
Click here to download some seeds I have prepared for countries, states and cities.
Copy those seed files into your the folder 'your app name / database / seeds'. Now in your database.php file, you need to call your seeds.
Within the 'run' function, include the following
...
$this->call(CountrySeeder::class);
$this->call(StateSeeder::class);
$this->call(CitySeeder::class);
...
Now you can run this artisan command,
php artisan db:seed
This will seed all the needed data into the database.
Now Let's begin building our API,
We need a controller, a repository, a repository interface and a service provider.
Let's create our controller, and name it LocationController
php artisan make:controller LocationController
Let's leave it for now, we will come back to it.
Now, let's create a folder called repositories within the app folder. And then create our LocationRepository.php and LocationRepositoryInterface.php files within the repositories folder.
Then, let's create a RepositoryServiceProvider file with the artisan command below.
php artisan make:provider RepositoryServiceProvider
Within the RepositoryServiceProvider we need to bind the repository to its interface as its done below.
//RepositoryServiceProvider.php
<?php
namespace App\Providers;
use App\Repositories\LocationRepositoryInterface;
use App\Repositories\LocationRepository;
class RepositoryServiceProvider extends ServiceProvider
{
public $bindings = [
LocationRepositoryInterface::class => LocationRepository;
]
}
Now, let's move to our LocationRepositoryInterface.php. Here we need to define the interfaces we will use later on in our LocationRepository.php
//LocationRepositoryInterface.php
<?php
namespace App\Repositories;
interface LocationRepositoryInterface
{
public function getAllCountries();
public function getAllStates();
public function getAllCities();
}
Then, let's move on to our LocationRepository.php, this is where all the main action happens. (i.e. this is where we query our models) !important.
//LocationRepository.php
<?php
namespace App\Repositories;
use App\City;
use App\Country;
use App\State;
class LocationRepository implements LocationRepositoryInterface
{
public function getAllCountries()
{
return Country::all();
}
public function getAllStates()
{
return State::all();
}
public function getAllCities()
{
return City::all();
}
}
Now, let finish finish up with our LocationController.php, here, we need to inject our Repository interface, also !important
. We will do that using the constructor function.
//LocationController.php
<?php
namespace App\Http\Controllers;
class LocationController extends Controller
{
private $locations; //can be called anything
public function __construct(LocationRepositoryInterface $locationRepository)
{
$this->locations = $locationRepository;
}
public function getAllCountries()
{
$countryData = $this->locations->getAllCountries(); //calling the repository function
return $countryData;
}
public function getAllStates()
{
$statesData = $this->locations->getAllStates();
return $statesData;
}
public function getAllCities()
{
$citiesData = $this->locations->getAllCities();
return $citiesData;
}
}
Finally, we can include our routes in the 'routes/Api.php' file
//Api.php
<?php
namespace App\routes;
use App\Http\Controllers\LocationController;
Route::get('countries', 'LocationController@getAllCountries');
Route::get('states', 'LocationController@getAllStates');
Route::get('cities', 'LocationController@getAllCities');
...
Now you can test your endpoints with postman.
Although Laravel by default will return your data in JSON, for a standard Api, you might want to format the Api response properly to have some supporting fields like message, error, and status code.
This is a miniature example of what you can achieve.
Go build something great!