Hokma School :: Course 2 Laravel

Laravel 10. API Development

테디아저씨 2026. 5. 9. 09:05

 

 

 

기존 웹 개발방식

브라우저요청 => HTML 반환

 

return view('posts.index',["posts"=>$posts]);

 

web

routes/web.php

 

 

api 개발방식

  • 모바일 앱
  • React/Vue 프론트엔드
  • 외부 서비스 연동
return response()->json($posts);

 

api 

routes/api.php

 

기본적으로 /api   를 추가로 가져간다.

 

** 11 버젼부터는 자동생성이 아닙니다.

** starter 구조가 많이 간소화됐습니다.

** 사용을 위해서 

 

bootstrap/app.php

->withRouting(
    web: __DIR__.'/../routes/web.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
)

 

=>

->withRouting(
    web: __DIR__.'/../routes/web.php',
    api: __DIR__.'/../routes/api.php',      // add this line
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
)

 

 

간단한 예시

주소데이터를 API로  보내주기

파일 pakistan_cities.csv

 

 

시더폴더에 저장
database/seeders/seederData/pakistan_cities.csv

 

Model

php artisan make:model Address -m

 

Migration 수정

database/migrations/xxxxx_create_addresses_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('addresses', function (Blueprint $table) {
            $table->id();
            $table->string('wikiDataId',50)->nullable();
            $table->string('type',50)->nullable();
            $table->string('city',50)->nullable();
            $table->string('name',50)->nullable();
            $table->string('country',50)->nullable();
            $table->string('countryCode',50)->nullable();
            $table->string('region',50)->nullable();
            $table->string('regionCode',50)->nullable();
            $table->string('regionWdId',100)->nullable();
            $table->decimal('latitude', 11, 8)->nullable();
            $table->decimal('longitude', 11, 8)->nullable();
            $table->integer('population')->default(0);

            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('addresses');
    }
};

 

make table

php artisan migrate

 

app/Models/Address.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Address extends Model
{
    //
    protected $fillable = [
        'id',
        'wikiDataId', 
        'type', 
        'city', 
        'name', 
        'country', 
        'countryCode', 
        'region', 
        'regionCode', 
        'regionWdId', 
        'latitude', 
        'longitude', 
        'population'];
   
}

 

Data 준비

 

make seeder

php artisan make:seeder AddressSeeder

 

database\seeders\AddressSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class AddressSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //

        $csvFile = fopen('database/seeders/seederData/pakistan_cities.csv', "r");
        $isFirstRow = true; // Flag to skip the first row

        while (($data = fgetcsv($csvFile, 1000, ",")) !== FALSE) {
            if ($isFirstRow) {
                $isFirstRow = false; // Skip the first row
                continue;
            }

            \App\Models\Address::create([
                'id' => $data[0],
                'wikiDataId' => $data[1],
                'type' => $data[2],
                'city' => $data[3],
                'name' => $data[4],
                'country' => $data[5],
                'countryCode' => $data[6],
                'region' => $data[7],
                'regionCode' => $data[8],
                'regionWdId' => $data[9],
                'latitude' => $data[10],
                'longitude' => $data[11],
                'population' => $data[12],
            ]);
        }

    }
}

 

seeding

php artisan db:seed AddressSeeder

 

 

API 만들기

routes/api.php

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AddressController;

Route::get('/address', [AddressController::class, 'index'])->name('address.index');

 

make Controller

php artisan make:controller AddressController

 

 

app/Http/Controllers/AddressController.php

<?php

namespace App\Http\Controllers;

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

class AddressController extends Controller
{
    //
    public function index(request $request)
    {
        $addresses = Address::all();
        return response()->json($addresses);
    }
}

 

http://127.0.0.1:8000/api/address

 

 

정상적으로 json 데이를 확인할 수 있습니다.

 

API CRUD

트럭사용 신청하기

 

 

Model

php artisan make:model TruckRequest -m

 

database/migrations/xxxx_create_truck_requests_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('truck_requests', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete();
            $table->string('name', 100)->nullable()->comment('name');
            $table->string('email', 100)->nullable()->comment('email');
            $table->string('phone', 100)->nullable()->comment('phone');
            $table->string('category', 100)->nullable()->comment('freight type');
            $table->string('weight', 50)->nullable();
            $table->string('departure', 100)->nullable()->comment('departure city');
            $table->string('destination', 100)->nullable()->comment('destination city');
            $table->boolean('service_express')->default(false)->comment('express delivery');
            $table->boolean('service_insurance')->default(false)->comment('insurance');
            $table->boolean('service_packaging')->default(false)->comment('packaging');
            $table->string('status', 1)->default('1')->comment('1: applying, 2: approved, 3: rejected');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('truck_requests');
    }
};

 

php artisan migrate

 

 

make Controller

php artisan make:controller Api/TruckRequestController -r

or 

php artisan make:controller Api/TruckRequestController --resource

 

* Api 를 붙인것은 폴더를 구분하고자 한 것일뿐 필수는 아닙니다.

* -r 

 

method list 

 

index() // 목록
create() // 작성폼
store() // 저장
show() // 상세
edit() // 수정폼
update() // 수정
destroy() // 삭제

 

 

view

resources/views/request/form.blade.php

<html>
<head>
    <title>Transportation HTML-5 Template </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h2>Request a Quote</h2>

            <!-- form -->
            <form id="request_form" method="POST" class="contact-form">
                @csrf
                <div class="row ">
                    <div class="col-lg-12 col-md-12 mb-3">
                        Name
                        <div class="input-form">
                            <input type="text" name="name" placeholder="Name" class="form-control">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        Phone
                        <div class="input-form">
                            <input type="text" name="phone" class="form-control" placeholder="Phone">
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 mb-3">
                        Phone
                        <div class="input-form">
                            <input type="text" name="email" class="form-control" placeholder="Email">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Freight Type</label>
                        <div class="select-items">
                            <select name="category" class="form-control">
                                <option value="">선택</option>
                                <option value="general">General</option>
                                <option value="refrigerated">Refrigerated</option>
                                <option value="hazardous">Hazardous</option>
                            </select>
                        </div>
                    </div>

                    <div class="col-lg-12 col-md-12 mb-3">
                        <label>Weight</label>
                        <div class="input-form">
                            <input type="text" name="weight" class="form-control" placeholder="Weight">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Departure City</label>
                        <div class="input-form">
                            <input type="text" name="departure" class="form-control" placeholder="City of Departure">
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 col-sm-6">
                        <label>Destination</label>
                        <div class="input-form">
                            <input type="text" name="destination" class="form-control" placeholder="City of Destination">
                        </div>
                    </div>
                    
                    <!-- Checkbox -->
                    <div class="col-lg-12 mb-3">
                        <div class="radio-wrapper mb-30 mt-15">
                            <label>Extra services:</label>
                            <div class="select-radio d-flex gap-3 flex-wrap">
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-2" name="service_express" type="checkbox">
                                    <label for="checkbox-2" class="radio-label ms-2 mb-0">Express Delivery</label>
                                </div>
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-4" name="service_insurance" type="checkbox">
                                    <label for="checkbox-4" class="radio-label ms-2 mb-0">Insurance</label>
                                </div>
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-5" name="service_packaging" type="checkbox">
                                    <label for="checkbox-5" class="radio-label ms-2 mb-0">Packaging</label>
                                </div>
                            </div>
                        </div> 
                    </div>
                </div>
            </form>	
            <div id="response_message" class="mt-3"></div>
            <!-- Button -->
            <div class="col-lg-12">
                <button type="button" onclick="create_request()" class="btn btn-primary">Request a Quote</button>
            </div>
    </div>
    <script>
        function create_request() {
            var box = document.getElementById('response_message');
            box.textContent = '';

            fetch('/api/truck_request', {
                method: 'POST',
                body: new FormData(document.getElementById('request_form')),
                headers: {
                    Accept: 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                },
            })
                .then(function (response) {
                    return response.json().then(function (data) {
                        if( response.ok ) {
                            box.className = 'mt-3 text-success';
                            box.textContent = '요청 성공';
                            location.href = '/request';
                        } else {
                            response.error.forEach(function (error) {
                                box.textContent += error.message + '\n';
                            });
                            box.className = 'mt-3 text-danger';
                        }
                        //box.className = 'mt-3 p-3 bg-light border rounded small';
                        //box.textContent = JSON.stringify(data, null, 2);
                    });
                })
                .catch(function () {
                    box.className = 'mt-3 text-danger';
                    box.textContent = '요청 실패2';
                });
        }
    </script>
    

</body>
</html>

 

 

make Controller for not API

php artisan make:controller RequestController -r

 

app/Http/Controllers/RequestController.php

public function create()
{
    // form
    return view('request.form');
}

 

api.php

use App\Http\Controllers\Api\TruckRequestController;
...


Route::post('/truck_request/request', [TruckRequestController::class, 'store'])->name('truck_request.store');

 

route

use App\Http\Controllers\RequestController;

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', [IndexController::class, 'dashboard'])->name('dashboard');
    Route::get('/myphoto', [UserController::class, 'myphoto'])->name('myphoto');
    Route::post('/myphoto', [UserController::class, 'myphoto_submit'])->name('myphoto.submit');
    Route::post('/myphoto/delete', [UserController::class, 'myphoto_delete'])->name('myphoto.delete');


    Route::get('/mytruck', [TruckController::class, 'mytruck'])->name('mytruck');
    Route::get('/truck_form', [TruckController::class, 'truck_form'])->name('truck_form');
    Route::post('/truck', [TruckController::class, 'truck_store'])->name('truck.store');


    // request
    Route::get('/request_form', [RequestController::class, 'create'])->name('request.create');
});

 

 

Store

 

app/Http/Controllers/Api/TruckRequestController.php

use App\Models\TruckRequest;    
...    
    
    public function store(Request $request)
    {

        // Accept: application/json 이면 실패 시 자동 422 + { message, errors } JSON
        $validated = $request->validate([
            'name' => 'required|string|min:2|max:100',
            'email' => 'required|email|max:100',
            'phone' => 'required|string|max:100',
            'weight' => 'required|string|max:50',
            'departure' => 'required|string|max:100',
            'destination' => 'required|string|max:100',
        ], [
            'name.required' => 'input name is required',   
            'email.required' => 'input email is required',
            'phone.required' => 'input phone is required',
            'weight.required' => 'input weight is required',
            'departure.required' => 'input departure is required',
            'destination.required' => 'input destination is required',
        ]);
        //
        $truckRequest = TruckRequest::create([
            //'user_id' => auth()->user()->id,
            'name' => $validated['name'],
            'email' => $validated['email'],
            'phone' => $validated['phone'],
            'weight' => $validated['weight'],
            'departure' => $validated['departure'],
            'destination' => $validated['destination'],
            'category' => $request->category,
            'service_express' => $request->boolean('service_express'),
            'service_insurance' => $request->boolean('service_insurance'),
            'service_packaging' => $request->boolean('service_packaging'), 
        ]);

        if( $truckRequest ) {
            return response()->json(['message' => 'Truck request created successfully'], 201);
        } else {
            return response()->json(['message' => 'Truck request creation failed'], 400);
        }
    }

 

List Page

 

resources/views/request/index.blade.php

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
  </head>
  <body>
    <div class="container mt-5 col-sm-12 mx-auto">
        <div class="row text-center mt-5">   
            <h1>
                Request List Page
            </h1>
            <div class="row mb-3">
                <div class="col-12 text-end">
                    <a href="{{ route('request.create') }}" class="btn btn-primary">Create Request</a>
                </div>
            </div>
            <div class="row" id="request-list"></div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
    <script>
        fetch('/api/truck_request', { headers: { Accept: 'application/json' } })
            .then(function (res) { return res.json(); })
            .then(function (items) {
                var list = document.getElementById('request-list');
                if (!list || !Array.isArray(items)) return;
                items.forEach(function (item) {
                    list.innerHTML +=
                        '<div class="col-12 card mb-2">' +
                        '<div class="card-body">' +
                        '<div class="d-flex flex-wrap gap-3 justify-content-between align-items-center">' +
                        '<span>' + item.name + '</span>' +
                        '<span>' + item.email + '</span>' +
                        '<span>' + item.weight + '</span>' +
                        '<span>' + item.departure + ' => ' + item.destination + '</span>' +
                        '<span class="text-muted small">' + item.created_at.split('T')[0] + '</span>' +
                        '</div>' +
                        '</div>' +
                        '</div>';
                    });
                })
                .catch(function (err) { console.error('Error:', err); });
        </script>
    </body>
</html>

 

 

app/Http/Controllers/RequestController.php

public function index()
{
    //
    // form
    return view('request.index');
}

 

routes/web.php

Route::get('/request_form', [RequestController::class, 'create'])->name('request.create');

// add to list page
Route::get('/request', [RequestController::class, 'index'])->name('request.index');

 

htttp://127.0.0.1:8000/request

 

 

Change to list page upon success

//box.textContent = JSON.stringify(data, null, 2);

location.href = '/request'

 

 

 

List Api

app/Http/Controllers/Api/TruckRequestController.php

public function index()
{
    //
    $truckRequests = TruckRequest::all();
    return response()->json($truckRequests);
}

 

routes/api.php

Route::post('/truck_request', [TruckRequestController::class, 'store'])->name('truck_request.store');
Route::get('/truck_request', [TruckRequestController::class, 'index'])->name('truck_request.index');

 

 

 

http://127.0.0.1:8000/api/truck_request

 

 

http://127.0.0.1:8000/request

 

 

 

 

Show

 

routes/web.php

Route::get('/request/{id}', [RequestController::class, 'show'])->name('request.show');

 

views/request/index.blade.php

 '<span>' + item.name + '</span>' +                        

to

 '<a href="{{ route('request.show', item.id) }}"><span>' + item.name + '</span></a>' +

 

app/Http/Controllers/RequestController.php

use App\Models\TruckRequest;

...


public function show(string $id)
{
    $truck_request = TruckRequest::findOrFail($id);
    return view('request.detail', ['truck_request' => $truck_request]);
}

 

 

resources/views/request/detail.blade.php

<html>
<head>
    <title>Transportation HTML-5 Template </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h2>Request a Quote</h2>

               <div class="row ">
                    <div class="col-lg-12 col-md-12 mb-3">
                        Name
                        <div class="input-form">
                            {{ $truck_request->name }}
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        Phone
                        <div class="input-form">
                            {{ $truck_request->phone }}
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 mb-3">
                        Email
                        <div class="input-form">
                            {{ $truck_request->email }}
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Freight Type</label>
                        <div class="select-items">
                           {{ $truck_request->category }}
                        </div>
                    </div>

                    <div class="col-lg-12 col-md-12 mb-3">
                        <label>Weight</label>
                        <div class="input-form">
                            {{ $truck_request->weight }}
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Departure City</label>
                        <div class="input-form">
                            {{ $truck_request->departure }}
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 col-sm-6">
                        <label>Destination</label>
                        <div class="input-form">
                            {{ $truck_request->destination }}
                        </div>
                    </div>
                    
                    <!-- Checkbox -->
                    <div class="col-lg-12 mb-3">
                        <div class="radio-wrapper mb-30 mt-15">
                            <label>Extra services:</label>
                            <div class="select-radio d-flex gap-3 flex-wrap">
                                {{ $truck_request->service_express ? 'Express Delivery' : '' }}
                                {{ $truck_request->service_insurance ? 'Insurance' : '' }}
                                {{ $truck_request->service_packaging ? 'Packaging' : '' }}
                            </div>
                        </div> 
                    </div>
                </div>
            <div id="response_message" class="mt-3"></div>
            <!-- Button -->
            <div class="col-lg-12">
                <a href="{{ route('request.edit', $truck_request->id) }}" class="btn btn-primary">Modify</a>
                <a href="{{ route('request.index') }}" class="btn btn-primary">List</a>
            </div>
    </div>

</body>
</html>

 

 

Edit Form

resources/views/request/edit.blade.php

<html>
<head>
    <title>Transportation HTML-5 Template </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h2>Request a Quote</h2>

            <!-- form -->
            <form id="request_form" method="POST" class="contact-form">
                @csrf
                <input type="hidden" name="id" value="{{ $truck_request['id'] }}">
                <div class="row ">
                    <div class="col-lg-12 col-md-12 mb-3">
                        Name
                        <div class="input-form">
                            <input type="text" name="name" placeholder="Name" class="form-control" value="{{ $truck_request['name'] }}">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        Phone
                        <div class="input-form">
                            <input type="text" name="phone" class="form-control" placeholder="Phone" value="{{ $truck_request['phone'] }}">
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 mb-3">
                        Email
                        <div class="input-form">
                            <input type="email" name="email" class="form-control" placeholder="Email" value="{{ $truck_request['email'] }}">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Freight Type</label>
                        <div class="select-items">
                            <select name="category" class="form-control">
                                <option value="">Type</option>
                                <option value="general" {{ $truck_request['category'] == 'general' ? 'selected' : '' }}>General</option>
                                <option value="refrigerated" {{ $truck_request['category'] == 'refrigerated' ? 'selected' : '' }}>Refrigerated</option>
                                <option value="hazardous" {{ $truck_request['category'] == 'hazardous' ? 'selected' : '' }}>Hazardous</option>
                            </select>
                        </div>
                    </div>

                    <div class="col-lg-12 col-md-12 mb-3">
                        <label>Weight</label>
                        <div class="input-form">
                            <input type="text" name="weight" class="form-control" placeholder="Weight" value="{{ $truck_request['weight'] }}">
                        </div>
                    </div>

                    <div class="col-lg-6 col-md-6 mb-3">
                        <label>Departure City</label>
                        <div class="input-form">
                            <input type="text" name="departure" class="form-control" placeholder="City of Departure" value="{{ $truck_request['departure'] }}">
                        </div>
                    </div>
                    <div class="col-lg-6 col-md-6 col-sm-6">
                        <label>Destination</label>
                        <div class="input-form">
                            <input type="text" name="destination" class="form-control" placeholder="City of Destination" value="{{ $truck_request['destination'] }}">
                        </div>
                    </div>
                    
                    <!-- Checkbox -->
                    <div class="col-lg-12 mb-3">
                        <div class="radio-wrapper mb-30 mt-15">
                            <label>Extra services:</label>
                            <div class="select-radio d-flex gap-3 flex-wrap">
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-2" name="service_express" type="checkbox" {{ $truck_request['service_express'] ? 'checked' : '' }}>
                                    <label for="checkbox-2" class="radio-label ms-2 mb-0">Express Delivery</label>
                                </div>
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-4" name="service_insurance" type="checkbox" {{ $truck_request['service_insurance'] ? 'checked' : '' }}>
                                    <label for="checkbox-4" class="radio-label ms-2 mb-0">Insurance</label>
                                </div>
                                <div class="checkbox d-flex align-items-center">
                                    <input id="checkbox-5" name="service_packaging" type="checkbox" {{ $truck_request['service_packaging'] ? 'checked' : '' }}>
                                    <label for="checkbox-5" class="radio-label ms-2 mb-0">Packaging</label>
                                </div>
                            </div>
                        </div> 
                    </div>
                </div>
            </form>	
            <div id="response_message" class="mt-3"></div>
            <!-- Button -->
            <div class="col-lg-12">
                <button type="button" onclick="create_request()" class="btn btn-primary">Request a Quote</button>
            </div>
    </div>
    <script>
        function create_request() {
            var box = document.getElementById('response_message');
            box.textContent = '';

            fetch('/api/truck_request/update', {
                method: 'POST',
                body: new FormData(document.getElementById('request_form')),
                headers: {
                    Accept: 'application/json',
                    'X-Requested-With': 'XMLHttpRequest',
                },
            })
                .then(function (response) {
                    return response.json().then(function (data) {
                        console.log(data);
                        if( response.ok ) {
                            box.className = 'mt-3 text-success';
                            box.textContent = '요청 성공';
                            location.href = '/request';
                        } else {
                            response.error.forEach(function (error) {
                                box.textContent += error.message + '\n';
                            });
                            box.className = 'mt-3 text-danger';
                        }
                        //box.className = 'mt-3 p-3 bg-light border rounded small';
                        //box.textContent = JSON.stringify(data, null, 2);
                    });
                })
                .catch(function () {
                    box.className = 'mt-3 text-danger';
                    box.textContent = '요청 실패2';
                });
        }
    </script>
    

</body>
</html>

 

 

Update

 

routes/api.php

Route::post('/truck_request/update', [TruckRequestController::class, 'update'])->name('truck_request.update');

 

app/Http/Controllers/Api/TruckRequestController.php

    public function update(Request $request)
    {
        //
        // Accept: application/json 이면 실패 시 자동 422 + { message, errors } JSON
        $validated = $request->validate([
            'id' => 'required|integer',
            'name' => 'required|string|min:2|max:100',
            'email' => 'required|email|max:100',
            'phone' => 'required|string|max:100',
            'weight' => 'required|string|max:50',
            'departure' => 'required|string|max:100',
            'destination' => 'required|string|max:100',
        ], [
            'id.required' => 'input id is required',
            'name.required' => 'input name is required',   
            'email.required' => 'input email is required',
            'phone.required' => 'input phone is required',
            'weight.required' => 'input weight is required',
            'departure.required' => 'input departure is required',
            'destination.required' => 'input destination is required',
        ]);

        $truckRequest = TruckRequest::findOrFail($request->input('id'));
        $truckRequest->name = $validated['name'];
        $truckRequest->phone = $validated['phone'];
        $truckRequest->email = $validated['email'];
        $truckRequest->weight = $validated['weight'];
        $truckRequest->departure = $validated['departure'];
        $truckRequest->destination = $validated['destination'];
        $truckRequest->category = $request->category;
        $truckRequest->service_express = $request->boolean('service_express');
        $truckRequest->service_insurance = $request->boolean('service_insurance');
        $truckRequest->service_packaging = $request->boolean('service_packaging');
        $updated = $truckRequest->save();

        if( $updated ) {
            return response()->json(['message' => 'Truck request updated successfully'], 200);
        } else {
            return response()->json(['message' => 'Truck request update failed'], 400);
        }        
        
    }

 

Delete

 

resources/views/request/detail.blade.php

<div class="col-lg-12">
    <a href="{{ route('request.edit', ['id' => $truck_request['id']]) }}" class="btn btn-primary">Modify</a>
    <a href="{{ route('request.index') }}" class="btn btn-primary">List</a>

    <!-- delete button -->
    <button type="button" onclick="delete_request()" class="btn btn-primary">Delete</button>
</div>

<form id="request_form" method="POST" class="contact-form">
    @csrf                
    <input type="hidden" name="id" value="{{ $truck_request['id'] }}">
</form>




<script>
    function delete_request() {
        var box = document.getElementById('response_message');
        box.textContent = '';
        fetch('/api/truck_request/delete', {
            method: 'POST',
            headers: {
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
            },
        })
            .then(function (response) {
                return response.json().then(function (data) {
                    console.log(data);
                    if( response.ok ) {
                        box.className = 'mt-3 text-success';
                        box.textContent = '요청 성공';
                        location.href = '/request';
                    } else {
                        response.error.forEach(function (error) {
                            box.textContent += error.message + '\n';
                        });
                        box.className = 'mt-3 text-danger';
        }
    }
            })
            .catch(function () {
                box.className = 'mt-3 text-danger';
                box.textContent = '요청 실패2';
            });
</script>

 

routes/api.php

Route::post('/truck_request/delete', [TruckRequestController::class, 'destroy'])->name('truck_request.destroy');

 

app/Http/Controllers/Api/TruckRequestController.php

public function destroy(Request $request)
{
    //
    // Accept: application/json 이면 실패 시 자동 422 + { message, errors } JSON
    $validated = $request->validate([
        'id' => 'required|integer',
    ], [
        'id.required' => 'input id is required',
    ]);
    $truckRequest = TruckRequest::findOrFail($request->input('id'));
    $deleted = $truckRequest->delete();
    if( $deleted ) {
        return response()->json(['message' => 'Truck request deleted successfully'], 200);
    } else {
        return response()->json(['message' => 'Truck request deletion failed'], 400);
    }
}

 

 

 

HTTP 상태

 

성공시

200 OK
201 Created

 

실패시

404 Not Found
422 Validation Error
500 Server Error