Spring boot로 JWT token authentication을 이용한 API server를 만들어 보기는 했지만 귀찮은 점이 많은데, 이전에 Laravel로 간단하게 만들었던 기억이 나서 다시 Laravel로 Token Authentication을 추가한 RESTful API Server를 만들어 보고자 한다.

1. Laravel project 만들기

composer create-project --prefer-dist laravel/laravel restapi

 

2. mysql db 생성

3. migration, model, controller 만들기

ldw@ldw-bmax:~/laravel/restapi  php artisan make:model -m -c --resource Book

 

<?php
............

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();
            $table->string('title', 10);
            $table->string('author', 10);
            $table->string('content', 20);
            $table->integer('pages');
            $table->timestamps();
        });
    }
    ................
};

 

4. migration

 ldw@ldw-bmax:~/laravel/restapi$ php artisan migrate

 

5. table 구조 확인

 

mysql> desc books;


+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| title      | varchar(10)         | NO   |     | NULL    |                |
| author     | varchar(10)         | NO   |     | NULL    |                |
| content    | varchar(20)         | NO   |     | NULL    |                |
| pages      | int(11)             | NO   |     | NULL    |                |
| created_at | timestamp           | YES  |     | NULL    |                |
| updated_at | timestamp           | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

 

6. 몇 개의 record를 직접 넣어 주었습니다.

mysql> select * from books;
+----+---------+--------+--------------------------+-------+------------+------------+
| id | title   | author | content                  | pages | created_at | updated_at |
+----+---------+--------+--------------------------+-------+------------+------------+
|  1 | laravel | lee    | laravel에 대한 기초      |   342 | NULL       | NULL       |
|  2 | spring  | kim    | spring boot 활용         |   425 | NULL       | NULL       |
|  3 | react   | park   | laravel api 와 react     |   212 | NULL       | NULL       |
+----+---------+--------+--------------------------+-------+------------+------------+
3 rows in set (0.01 sec)

 

7. Rescource 생성

ldw@ldw-bmax:~/laravel/restapi$ php artisan make:resource BookResource

 

만들어진 BookResource 파일 수정

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BookResource extends JsonResource
{
    /**
    * Transform the resource into an array.
    *
    * @return array<string, mixed>
    */
    public function toArray(Request $request): array
    {
        //별 변화가 없으면 defalult로
        //return parent::toArray($request);

        //필요한 attribute만 json으로 만들려면 다음과 같이
        return [
            'id' => $this->id,
            'name' => $this->title,
            'author' => $this->author,
            'content' => $this->content,
            'pages' => $this->pages,
        ];
    }

    // response를 다시 customize해주는 withResponse method를 overide해서
    // charset 과 encoding을 바꾸어 주어 한글이 제대로 보이게 함
    public function withResponse($request, $response)
    {
        $response->header('Charset', 'utf-8');
        $response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
    }
}

 

8. Controller에 function 추가

BookResource를 이용해 Json 을 return 가능

 

app/Http/Controllers/BookController 

<?php

namespace App\Http\Controllers;

use App\Models\Book;
use Illuminate\Http\Request;
use App\Http\Resources\BookResource;

class BookController extends Controller{
    /**
    * Display a listing of the resource.
    */
    public function index()
    {
        $books = Book::all();
        return BookResource::collection($books);
    }

    /**
    * Display the specified resource.
    */
    public function show(Book $book)
    {
        return new BookResource(Book::findOrFail($book->id));
    }
    ................
}
 

 

9 Route 생성

routers/api.php

 

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BookController;

...............................

Route::get('/books', [BookController::class, 'index']);

Route::get('/books/{book}', [BookController::class, 'show']);

 

10. Web page에서 다음과 같은 api로 조회 가능

localhost:8000/api/books

{
    "data": [
        {
            "name": "laravel",
            "author": "lee",
            "content": "laravel에 대한 기초",
            "pages": 342
        },
        {
            "name": "spring",
            "author": "kim",
            "content": "spring boot 활용",
            "pages": 425
        },
        {
            "name": "react",
            "author": "park",
            "content": "laravel api 와 react",
            "pages": 212
        }
    ]
}

 

11. React project를 만들고 결과 조회

 

Home.js

import {Button, Container, Table} from 'react-bootstrap'
import axios from "axios"
import { useEffect, useState} from 'react'

export const Home = () => {

    const [books, setBooks] = useState([])

    const getBook = async () => {
    try {
        const result = await axios.get( "http://localhost:8000/api/books" )
        console.log(result.data)
        setBooks(result.data.data)
    } catch ( err){
        console.log( err )
    }
}

useEffect( () => {
    getBook()
}, [])
 
return (
    <Container>
        Books
        
        <Table striped bordered>
        <thead>
            <tr>
                <th>Title</th>
                <th>Author</th>
                <th>Content</th>
                <th>Pages</th>
            </tr>
        </thead>
        <tbody>
            {books?.map((book, index) => (
                <tr key={index}>
                    <td>{book.name}</td>
                    <td>{book.author}</td>
                    <td>{book.content}</td>
                    <td>{book.pages}</td>
                </tr>
            ))}
        </tbody>
        </Table>
    </Container>
)
 
}

 

 

12. 결과 test

localhost:3000으로 접속

 

 

다음은 REST 기능에 맞게 create, update, delete에 대한 기능을 추가해 본다

+ Recent posts