PHP
Create folder 'php-project' and go into it.
Once there, clone laradock project.
Afther, create the 'web' folder.
Go to laradock folder. Take note this is not the folder we made above.
Copy the environment settings.
mkdir php-project &&\
cd php-project &&\
git clone https://github.com/laradock/laradock.git &&\
mkdir web &&\
cd laradock &&\
cp env-example .env
Set project folder into php-project/laradock/.env file.
APP_CODE_PATH_HOST=../web/
Run docker-compose in php-project/laradock folder.
docker-compose up -d nginx mysql
Go into the container.
sudo docker-compose exec workspace bash
Clone laravel project into the container and be sure to write a dot at the end, to pointing out to COMPOSER (the package installer) that it has to place the source downloaded into the current folder.
composer create-project --prefer-dist laravel/laravel="6.0.*" .
Alternatively, you can download the final source code of this tutorial using git and composer. If this is the case, you will see all the following steps already implemented.
git clone https://github.com/federicozacayan/restful-api-php.git . && composer install
Configure environment variables in Laravel related to the database connection.
Take the values from php-project/laradock/.env.
...
MYSQL_DATABASE=default
MYSQL_USER=default
MYSQL_PASSWORD=secret
...
And set the values in php-project/web/.env (or in /var/www/.env if you are into the container).
...
DB_HOST=mysql
DB_DATABASE=default
DB_USER=default
DB_PASSWORD=secret
...
As you can see, we have replaced 127.0.0.1 by mysql, which is the name of the hostname asigned to mysql.
Set permission to the project folder (php-project/web/ or /var/www/).
sudo chmod -R 777 .
Check laravel application.
http://localhost
You can go out of the container just writing exit.
root@bb281fc97634:/var/www# exit
You can stop docker-compose executing the following command in the php-project/laradock/ folder.
sudo docker-compose stop
Or you can down docker-compose
sudo docker-compose down
Now, we can continue developing this RESTful application.
So, if you stop or down the docker-compose, please run docker-compose again and go into the container as we mentioned before.
Then, create a module named Product.
php artisan make:model Product --all
Add some fields into the database/migrations/xxxx_xx_xx_xxxxxx_create_products_table.php.
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
}
Enable fillable fields into the Model in app/Product.php
class Product extends Model
{
protected $fillable =['name','description'];
}
Set the factory fields in the factory file in database/factories/ProductFactory.php using faker.
$factory->define(Product::class, function (Faker $faker) {
return [
'name' => $faker->name,
'description' => $faker->unique()->email
];
});
Create a seeder by console.
php artisan make:seeder ProductSeeder
Call the factory in database/seeds/ProductSeeder.php.
public function run()
{
factory(App\Product::class,2)->create();
}
Set the general database seeder in database/seeds/DatabaseSeeder.php
public function run()
{
$this->call(ProductSeeder::class);
}
Run the migration and the seeder.
php artisan migrate:refresh --seed
It will appear the following error.
Illuminate\Database\QueryException : SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from information_schema.tables where table_schema = default and table_name = migrations and table_type = 'BASE TABLE')
To solve this issue you have to go into mysql container and alter the way the users are identified and configure mysql_native_password way.
Check the mysql container name (probably 'laradock_mysql_1'), and go into it.
sudo docker exec -it laradock_mysql_1 bash
Once inside, connect the databse using mysql client.
root@randon123:/# mysql -u root -p
Use the password in located in php-project/laradock/.env, which is root.
MYSQL_ROOT_PASSWORD=root
Then, you must modify the form of identification that the user uses.
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
Query OK, 0 rows affected (0.08 sec)
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
Query OK, 0 rows affected (0.11 sec)
mysql> ALTER USER 'default'@'%' IDENTIFIED WITH mysql_native_password BY 'secret';
Query OK, 0 rows affected (0.14 sec)
In this way you solve this issue.
But, if the table 'products' already exist and appear other issue with that. Run tinker and then delete the table.
php artisan tinker
Schema::drop('products');
To generate routes go to routes/api.php and write the following.
Route::apiResource('Product', 'ProductController');
Then, in app/Providers/RouteServiceProvider.php write the following.
public function boot()
{
...
Route::model('Product', \App\Product::class);
...
}
With this step, we mapping the url http://localhost/api/Product with the Product model.
That enable to inject an instance of the model in the methods of the ProductController, as we will see in the next steps.
In app/Http/Controllers/ProductController.php we have to write the following methods.
public function index() {
return Product::all();
}
public function show(Product $product) {
return $product;
}
public function store(Request $request) {
$product = Product::create($request->all());
return response()->json($product, 201);
}
public function update(Request $request, Product $product) {
$product->update($request->all());
return response()->json($product, 200);
}
public function destroy(Product $product) {
$product->delete();
return response()->json(null, 204);
}
Now, you cant test the aplication with any API Rest consumer. In the following url.
http://localhost/Product