Download Laravel App
composer create-project --prefer-dist laravel/laravel my-app
C:\xampp\htdocs\laravel10project>composer create-project laravel/laravel laravel10project
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=root
DB_PASSWORD=
Create Model and Migration
C:\xampp\htdocs\laravel\laravelproject>php artisan make:model Product -m
A new file named Product.php will be created in the app directory and database/migrations directory to generate the table in our database
app/Models/Product.php
//app/Models/Product.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; protected $fillable = [ 'name', 'image', 'description' ]; }database\migrations\create_products_table.php
//database\migrations\create_products_table.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('image'); $table->text('description'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('products'); } };Database Migration
php artisan migrate
C:\xampp\htdocs\laravel\laravel10project>php artisan migrate
Migration table created successfully.
check database table
Create Controller and Request
C:\xampp\htdocs\laravel\laravel10project>php artisan make:controller ProductController -r
app\Http\Controllers\ProductController.php
//app\Http\Controllers\ProductController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; use App\Http\Requests\ProductStoreRequest; use Illuminate\Support\Str; use Illuminate\Support\Facades\Storage; //php artisan storage:link = php artisan storage:link = http://127.0.0.1:8000/storage/1.jpg class ProductController extends Controller { public function index() { //$products = Product::all(); // All Product $products = Product::paginate(4); // Return Json Response return response()->json([ 'results' => $products ],200); } public function store(ProductStoreRequest $request) { try { $imageName = Str::random(32).".".$request->image->getClientOriginalExtension(); // Create Product Product::create([ 'name' => $request->name, 'image' => $imageName, 'description' => $request->description ]); // Save Image in Storage folder Storage::disk('public')->put($imageName, file_get_contents($request->image)); // Return Json Response return response()->json([ 'message' => "Product successfully created." ],200); } catch (\Exception $e) { // Return Json Response return response()->json([ 'message' => "Something went really wrong!" ],500); } } }Next, create a Request
C:\xampp\htdocs\laravel\laravel10project>php artisan make:request ProductStoreRequest
app\Http\Requests\ProductStoreRequest.php
//app\Http\Requests\ProductStoreRequest.php <?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class ProductStoreRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ public function authorize(): bool { //return false; return true; } /** * Get the validation rules that apply to the request. * * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string> */ public function rules(): array { if(request()->isMethod('post')) { return [ 'name' => 'required|string|max:258', 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'description' => 'required|string' ]; } else { return [ 'name' => 'required|string|max:258', 'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048', 'description' => 'required|string' ]; } } public function messages() { if(request()->isMethod('post')) { return [ 'name.required' => 'Name is required!', 'image.required' => 'Image is required!', 'description.required' => 'Descritpion is required!' ]; } else { return [ 'name.required' => 'Name is required!', 'description.required' => 'Descritpion is required!' ]; } } }Routes
All API requests will need the header Accept: application/json.
open routes/api.php and update the following code
routes\api.php
//routes\api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\ProductController; Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); }); Route::get('products', [ProductController::class, 'index']); Route::post('products', [ProductController::class, 'store']);generate symbolic links C:\xampp\htdocs\laravel\laravel10project>php artisan storage:link
Run C:\xampp\htdocs\laravel\laravel10project>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
open postman new request
GET api/products Index All products return.
GET : http://127.0.0.1:8000/api/products
POST api/products Store Create a new product.
POST : http://127.0.0.1:8000/api/products
body
key value
name Iphone 13
image iphone.jpg = file
description product description
React JS
https://create-react-app.dev/
Create Project
C:\react-js>npx create-react-app myreactdev
Run
C:\react-js\myreactdev> npm start
https://github.com/axios/axios
Installing the Axios Client
$ npm install axios
C:\reactdev\myreactdev>npm install axios
C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js import React, { useEffect, useState } from "react"; import axios from "axios"; // Component import Navbar from "./Component/Navbar"; import ProductList from "./Component/ProductList"; function App() { const [products, setProducts] = useState([]); const [info, setInfo] = useState({}); const url = "http://127.0.0.1:8000/api/products"; const fetchProducts = (url) => { axios .get(url) .then((data) => { setProducts(data.data.results.data); //console.log(data.data.results.data); setInfo(data.data.results); //console.log(data.data.results.next_page_url); }) .catch((error) => { console.log(error); }); }; const handleNextPage = () => { fetchProducts(info.next_page_url); window.scrollTo(0, 0); }; const handlePreviousPage = () => { fetchProducts(info.prev_page_url); window.scrollTo(0, 0); }; useEffect(() => { fetchProducts(url); }, []); return ( <> <Navbar brand="Cairocoders" /> <div className="container py-5"><p><h2>React js Laravel 10 REST API Show Product List with pagination Next Prev</h2></p> <nav> <ul className="pagination justify-content-center"> {info.prev_page_url ? ( <li className="page-item"> <button className="page-link" onClick={handlePreviousPage}> Previous </button> </li> ) : null} {info.next_page_url ? ( <li className="page-item"> <button className="page-link" onClick={handleNextPage}> Next </button> </li> ) : null} </ul> </nav> </div> <ProductList products={products} /> <div className="container pb-5"> <nav> <ul className="pagination justify-content-center"> {info.prev_page_url ? ( <li className="page-item"> <button className="page-link" onClick={handlePreviousPage}> Previous </button> </li> ) : null} {info.next_page_url ? ( <li className="page-item"> <button className="page-link" onClick={handleNextPage}> Next </button> </li> ) : null} </ul> </nav> </div> </> ); } export default App;C:\react-js\myreactdev\src\Component\Navbar.js
//C:\react-js\myreactdev\src\Component\Navbar.js import React from "react"; const Navbar = ({ brand }) => { return ( <nav className="navbar navbar-dark bg-dark"> <div className="container"> <a className="navbar-brand text-uppercase" href="/"> {brand} </a> </div> </nav> ); }; export default Navbar;C:\react-js\myreactdev\src\Component\ProductList.js
//C:\react-js\myreactdev\src\Component\ProductList.js import React from "react"; const ProductList = ({ products }) => { return ( <div className="container"> <div className="row"> {products.map((item, index) => ( <div key={index} className="col-lg-3 col-md-6 col-sm-12 mb-4"> <div className="card" style={{ minWidth: "200px" }}> <img src={`http://127.0.0.1:8000/storage/${item.image}`} alt="Product list" className="card-img-top" /> <div className="card-body"> <h5 className="card-title">{item.name}</h5> <hr /> <p className="card-text">Description: {item.description}</p> </div> </div> </div> ))} </div> </div> ); }; export default ProductList;react-js\myreactdev\src\Index.css
//react-js\myreactdev\src\index.css body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background-color: #000000; overflow-x: hidden; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; } h2 { color:#fff; }react-js\myreactdev\public\index.html
//react-js\myreactdev\public\index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>React App</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>Run C:\react-j\myreactdev>npm start
http://localhost:3000/