Pada tutorial kali ini, kita akan Membuat RESTful API dengan Laravel sebagai backend untuk mengelola todo dan kita gunakan react sebagai frontend. Kita akan pisah antara frontend dan backend supaya lebih mudah mempelajari kedua programming language yang saat ini sangat powerfull. 

Bagian 1: Backend Laravel

Langkah 1: Inisialisasi Laravel Project

composer create-project laravel/laravel todo-api
cd todo-api

Langkah 2: Buat Model, Migration & Controller

php artisan make:model Todo -mcr

Edit migration di database/migrations/xxxx_create_todos_table.php:

Schema::create('todos', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->boolean('completed')->default(false);
    $table->timestamps();
});

Lakukan migrate

php artisan migrate

Langkah 3: Isi Controller dan model Todo

Buka app/Http/Controllers/TodoController.php:

use App\Models\Todo;
use Illuminate\Http\Request;

class TodoController extends Controller
{
    public function index()
    {
        return Todo::orderBy('created_at', 'desc')->get();
    }

    public function store(Request $request)
    {
        $request->validate(['title' => 'required']);
        return Todo::create([
            'title' => $request->title,
            'completed' => false,
        ]);
    }

    public function update(Request $request, Todo $todo)
    {
        $todo->update($request->only(['title', 'completed']));
        return $todo;
    }

    public function destroy(Todo $todo)
    {
        $todo->delete();
        return response()->json(['message' => 'Deleted']);
    }
}

Dan tambahkan fillable untuk Models/todo.php menjadi sebagai berikut:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    protected $fillable = [
        'title',
        'completed'
    ];
}

Langkah 4: Tambahkan Routing API

Sebelum ke routing, laravel 11 tidak menyertakan routes/api.php lagi, sehingga kita perlu install api dengan command berikut:

php artisan install:api

Edit routes/api.php:

use App\Http\Controllers\TodoController;

Route::apiResource('todos', TodoController::class);

Langkah 5: Test API
Kamu bisa gunakan Postman atau REST Client. Contoh:

Tambah Todo

POST /api/todos
Content-Type: application/json

{
  "title": "Belajar React"
}

todos post

Ambil data todo

GET /api/todos

Update Todo

PUT /api/todos/1
Content-Type: application/json

{
  "completed": true
}

Update todo

Hapus Todo

DELETE /api/todos/1

 

Bagian 2: Frontend React

  • Menggunakan React + Axios untuk berinteraksi dengan Laravel API

  • Menampilkan, menambah, menghapus, dan menandai todo

  • Mengelola state dengan React Hooks (useState, useEffect)

Tools yang akan kita gunakan:

  • Node.js & NPM

  • Vite (lebih cepat dari CRA)

  • Axios (untuk HTTP request)

  • Tailwind CSS (optional, buat tampilan lebih rapi)

Langkah 1: Setup Proyek React

npm create vite@latest todo-react-frontend --template react
cd todo-react-frontend
npm install
npm install axios

Jika ada pilihan saat instalasi react, silahkan pilih berikut:

 Select a framework:
│  React
│
◇  Select a variant:
│  JavaScript

Install tailwind CSS

npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init

Edit tailwind.config.js:

content: ["./index.html", "./src/**/*.{js,jsx}"],

Di src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

Lalu kita rebuild index.css dengan perintah berikut:

npx tailwindcss -i ./src/index.css -o ./src/output.css --watch

Maka akan membuat file bernama src/output.css di folder src. Lalu kita edit src/Main.jsx menjadi berikut:

import './output.css'

Langkah 2: Konfigurasi Axios

Buat file src/api.js:

import axios from 'axios';

export default axios.create({
  baseURL: 'http://localhost:8000/api', // Ganti sesuai host Laravel-mu
});

Langkah 3: Komponen TodoApp

Buat file src/TodoApp.jsx:

import { useState, useEffect } from 'react';
import api from './api';

function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState('');

  const fetchTodos = async () => {
    const res = await api.get('/todos');
    setTodos(res.data);
  };

  const addTodo = async (e) => {
    e.preventDefault();
    if (!newTodo) return;
    await api.post('/todos', { title: newTodo });
    setNewTodo('');
    fetchTodos();
  };

  const toggleTodo = async (id, completed) => {
    await api.put(`/todos/${id}`, { completed: !completed });
    fetchTodos();
  };

  const deleteTodo = async (id) => {
    await api.delete(`/todos/${id}`);
    fetchTodos();
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <div className="max-w-md mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">Todo App (React + Laravel)</h1>

      <form onSubmit={addTodo} className="flex gap-2 mb-4">
        <input
          type="text"
          className="border p-2 w-full"
          placeholder="New todo..."
          value={newTodo}
          onChange={(e) => setNewTodo(e.target.value)}
        />
        <button className="bg-blue-500 text-white px-4 py-2">Add</button>
      </form>

      <ul>
        {todos.map((todo) => (
          <li key={todo.id} className="flex justify-between mb-2 items-center">
            <div>
              <input
                type="checkbox"
                checked={todo.completed}
                onChange={() => toggleTodo(todo.id, todo.completed)}
              />
              <span className={todo.completed ? 'line-through text-gray-500 ml-2' : 'ml-2'}>
                {todo.title}
              </span>
            </div>
            <button onClick={() => deleteTodo(todo.id)} className="text-red-500">✕</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoApp;

Langkah 4: Pasang Komponen ke App

src/App.jsx:

import TodoApp from './TodoApp';

function App() {
  return (
    <div className="bg-gray-100 min-h-screen p-6">
      <TodoApp />
    </div>
  );
}

export default App;

Langkah 5: CORS di Laravel

Agar frontend bisa akses API backend Laravel, pastikan di config/cors.php:

'paths' => ['api/*'],
'allowed_origins' => ['http://localhost:5173'], // alamat React

Lakukan clear config berikut:

php artisan config:clear

Jalankan Aplikasi:

Backend Laravel:

php artisan serve

Frontend React:

npm run dev

Buka: http://localhost:5173

Jika berhasil, akan menghasilkan sebagai berikut:

todo app laravel react