L o a d i n g
Laravel CRUD example with vue3 composition api & jest unit tests BackEnd Development

Laravel CRUD example with vue3 composition api & jest unit tests

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
Enter fullscreen mode Exit fullscreen mode

.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>

...
Enter fullscreen mode Exit fullscreen mode

Run composer install and migrate your database

composer install
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Set up laravel/ui scaffolding and scaffold ui

composer require Laravel/ui     
php artisan ui bootstrap   auth
npm install && npm run dev 
Enter fullscreen mode Exit fullscreen mode

Run your laravel starter app

php artisan key:generate
php artisan serve
Enter fullscreen mode Exit fullscreen mode

2. Models

Use artisan to generate our model with migration.

php artisan make:model Book  m
Enter fullscreen mode Exit fullscreen mode

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');
}
Enter fullscreen mode Exit fullscreen mode

Book model.

// app/models/book.php
class Book extends Model
{
    use HasFactory;
    protected $fillable = ['title' , 'year', 'genre',                                                   
                           'author','publisher'];
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
// 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)]
         ]);
   }
}

Enter fullscreen mode Exit fullscreen mode

Call test data seeder in application database seeder

// database/seeders/DatabaseSeeder.php

public function run()
{
   $this >call([
       BookSeeder::class
   ]);
}
Enter fullscreen mode Exit fullscreen mode

Finally, migrate and seed database.

php artisan migrate   seed
Enter fullscreen mode Exit fullscreen mode

3. Controllers and routes

Create the books controller (this will be our API).

php artisan make:controller Api/BookController   resource   api   model=Book
Enter fullscreen mode Exit fullscreen mode

Create resources and leave as is.

php artisan make:resource BookResource 
Enter fullscreen mode Exit fullscreen mode

Create requests and update the rules array as follows

php artisan make:request BookRequest 
Enter fullscreen mode Exit fullscreen mode
// app/Http/Requests/BookRequest.php
public function rules()
{
    return [
        'year' => ['required', 'integer'],
        'title' => ['required', 'string'],
        'genre' => ['required', 'string'],
        'author' => ['required', 'string'],
        'publisher' => ['required', 'string'],
    ];
}

Enter fullscreen mode Exit fullscreen mode

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();
    }
}

Enter fullscreen mode Exit fullscreen mode

Finally let's tie our controller to our routes.

// App/routes/api.php

use AppHttpControllersApiBookController;

// ... 

Route::apiResource('books', BookController::class);
Enter fullscreen mode Exit fullscreen mode

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.