book store example app
We will be setting up an example laravel app with a vuejs3 frontend as well as typescript and unit tests for our vue components.
1. Set up laravel project
Let's set up new laravel project with new .env file
laravel new laravel online books && cd laravel online books
cp .env.example .env
.env
APP_NAME="Online books"
...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<YOUR_DB>
DB_USERNAME=<YOUR_DB_USER>
DB_PASSWORD=<YOUR_DB_PASSWORD>
...
Run composer install and migrate your database
composer install
php artisan migrate
Set up laravel/ui scaffolding and scaffold ui
composer require Laravel/ui
php artisan ui bootstrap auth
npm install && npm run dev
Run your laravel starter app
php artisan key:generate
php artisan serve
2. Models
Use artisan to generate our model with migration.
php artisan make:model Book m
create_book table migration
// database/migrations/202x_xxx_create_books_table.php
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table >id();
$table >string('title');
$table >integer('year');
$table >string('genre');
$table >string('author');
$table >string('publisher');
$table >timestamps();
});
}
public function down()
{
Schema::dropIfExists('books');
}
Book model.
// app/models/book.php
class Book extends Model
{
use HasFactory;
protected $fillable = ['title' , 'year', 'genre',
'author','publisher'];
}
3. Seed the database with test data
you can skip this section but it's nice to have test data to start off.
php artisan make:seeder BookSeeder
// database/seeders/BookSeeder.php
public function run()
{
$authors = ['Terry A', 'Steven Price', 'John Smith'];
$genres = ['Fiction','Non Fiction','Business','Horror'];
$publishers = ['Publisher A','Publisher B','Publisher C'];
for ($i = 0; $i <= 10; $i++) {
DB::table('books') >insert(
[
'title' => "Book title {$i}",
'year' => rand(1995, 2021),
'genre' => $genres[rand(0, count($genres) 1)],
'author' => $authors[rand(0, count($authors) 1)],
'publisher' => $publishers[rand(0,
count($publishers) 1)]
]);
}
}
Call test data seeder in application database seeder
// database/seeders/DatabaseSeeder.php
public function run()
{
$this >call([
BookSeeder::class
]);
}
Finally, migrate and seed database.
php artisan migrate seed
3. Controllers and routes
Create the books controller (this will be our API).
php artisan make:controller Api/BookController resource api model=Book
Create resources and leave as is.
php artisan make:resource BookResource
Create requests and update the rules array as follows
php artisan make:request BookRequest
// app/Http/Requests/BookRequest.php
public function rules()
{
return [
'year' => ['required', 'integer'],
'title' => ['required', 'string'],
'genre' => ['required', 'string'],
'author' => ['required', 'string'],
'publisher' => ['required', 'string'],
];
}
Now our controller to support CRUD operations.
App/http/controllers/api/BookController.php
<?php
namespace AppHttpControllersApi;
use AppHttpControllersController;
use AppHttpRequestsBookRequest;
use AppHttpResourcesBookResource;
use AppModelsBook;
class BookController extends Controller
{
/**
* Get all books
**/
public function index()
{
return BookResource::collection(Book::all());
}
/**
* Store a book
**/
public function store(BookRequest $request)
{
$book = Book::create($request >validated());
return new BookResource($book);
}
/**
* Get one book
**/
public function show(Book $book)
{
return new BookResource($book);
}
/**
* Update a book
**/
public function update(BookRequest $request, Book $book)
{
$book >update($request >validated());
return new BookResource($book);
}
/**
* Delete a book
**/
public function destroy(Book $book)
{
$book >delete();
return response() >noContent();
}
}
Finally let's tie our controller to our routes.
// App/routes/api.php
use AppHttpControllersApiBookController;
// ...
Route::apiResource('books', BookController::class);
Now test this by hitting localhost:8000/api/books with your server running.
4. Set up vue3 frontend
I recommend that you use node version 12 as my set up is.
nvm use v12