バックエンドとフロントエンドを切り分けた環境で、バックエンドのデータをフロントエンドに表示させる部分を学習中です。
今回は、データベースのデータを取得するAPIを作って、fetchとasync/awaitでフロント側に表示させることに成功したので、
流れを備忘録として残しておきます。
前提
- フロントエンドとバックエンドを切り分けている
- 自作APIを用いる
- データベースを使用する
- PostgreSQL
環境
- PHP 8.1.7
- Laravel Framework 9.18.0
- psql (PostgreSQL) 14.4
- MacOS Monterey 12.2.1
開発手順
1. バックエンド、フロントエンドでそれぞれディレクトリを用意し、別々にターミナルを開いて移動しておく
mkdir todo-api
cd todo-api
mkdir todo-front
cd todo-front
2. フロントエンドのファイルを構成する
- todo-front
- index.html
3. バックエンドのファイルを構成する(Laravelを使う)
composer create-project laravel/laravel --prefer-dist todo-api
このコマンドで、todo-apiというディレクトリ配下にLaravelがよしなにファイルを構成してくれます。
ただ、今回LaravelではAPIを作るだけであり、MVCのVの部分はフロント側で作成するので、blade系は必要のないファイルになります。
とりあえず気にせず続行します。
4. データベース接続
今回はPostgreSQLを使用します。
過去に自分がまとめた記事を見ながら、データベースを作成します。
今回は、以下のようなデータベースを用意しました。なお、テーブルやカラムは後でMigrationにより入れていきます。
データベース名:ToDoApp
5. Laravel側から接続する
.envファイルのDB部分を以下のように変更する。
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=データベース名
DB_USERNAME=ユーザ名
DB_PASSWORD=パスワード
6 モデルの作成
php artisan make:model Todo -m
これで以下ファイルが自動的に作成されます。
- database/migrations/にxxxx_create_todos_table.php
- app/Models/Todo.php
以下のように、Migrationファイルにデータベースの設計書を記述していきます。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('todos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('memo')->nullable();
$table->smallInteger('status')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('todos');
}
};
これを「php artisan migrate」することで、先ほど作成したデータベースの中にテーブルとカラムが一括で追加されます。
では実行します。
php artisan migrate
以下のようにテーブル名を確認すると、ちゃんとカラムが作られていますね!
ただしデータが空っぽなので、試しに1件入れてみます。
データ挿入
insert into todos values (1, '洗濯', 0);
中身チェック
SELECT * FROM todos
今度は中身も入りました!
7. コントローラの作成
次のコマンドで、APIモードでコントローラを作成できます。
php artisan make:controller TodoController --api
とりあえず簡単なAPIを作ってみます。
データベースから全てのデータを取得するAPIです。
<?php
namespace App\Http\Controllers;
use App\Models\Todo;
class TodoController extends Controller
{
public function index()
{
$todoIndex = Todo::all();
return $todoIndex;
}
}
8. ルーティング
ルーティングは、APIの場合はroutes/api.phpに記述するのが理想ですが、今回は一番基本のroutes/web.phpに記述してみます。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodoController;
use Illuminate\Http\Request;
Route::get('/', function () {
return view('welcome');
});
// 追記
Route::controller(TodoController::class)->group(function () {
Route::get('api/todo/index', [TodoController::class, 'index']);
});
これでURIの設定ができたはずなので、下記コマンドでチェックしてみます。
php artisan route:list
上記画像の通り、api/todo/indexにアクセスしたらTodoControllerのindexアクションにアクセスされる、というルーティングが作られているのが確認できました!
9. ローカルサーバ立ち上げ
ではブラウザでも確認してみます。
Laravelが用意してくれているコマンドを使ってビルトインサーバ(デフォルトの8000番ポート)を立ち上げ、ブラウザで下記URLにアクセスしてみましょう。
php artisan serve
http://localhost:8000/api/todo/index
データベースのデータを取得できているのが分かります!
しかし日本語が文字化けしてしまっているので、コントローラを下記のように修正します。
<?php
namespace App\Http\Controllers;
use App\Models\Todo;
class TodoController extends Controller
{
public function index()
{
$todoIndex = Todo::all();
/*******************************************
変数の配列に日本語が含まれる場合には
JSON_UNESCAPED_UNICODEオプションを指定することで
正常に日本語をJSON形式に変換することができます。
*******************************************/
$encode_array = json_encode($todoIndex, JSON_UNESCAPED_UNICODE);
return $encode_array;
}
}
日本語がちゃんと変換されて表示されていますね。
10. フロント側からAPIを叩く
最後に、フロント側からAPIを叩いて表示させてみます。
手順1でバックエンド、フロントエンドで別々にターミナルを開いておいたと思いますので、フロントエンド用のターミナルに移っておきます。
todo.htmlを下記のように編集して、APIと連携させます。
今回はfetchとasync/awaitを使用しています。
なお、fetchの引数はAPIのURLを書きますが、これはroutes/web.phpで指定しておいたルーティングを書きます。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
/************************************************++*******
APIを呼び出してデータをコンソールに表示させる
*********************************************************/
async function callApi() {
const res = await fetch("http://localhost:8000/api/todo/index");
const index = await res.json();
console.log(index);
}
callApi();
</script>
</body>
</html>
それでは、バックとフロントが連携できたか確認するため、ブラウザのコンソールを開いて見てみましょう。
フロント側はLaravelとは切り離して構成しているため、Laravelの便利コマンド(php artisan〜)は使用できません。
そのため下記コマンドでビルトインサーバを立ち上げます。
なお、8000番ポートはバックエンド側で使用中のため、フロントエンド側では3000番ポートとしておきたいと思います。
php -S localhost:3000
http://localhost:3000/todo.html
コンソールを確認すると、ちゃんとデータが返ってきています!
無事に連携ができたので、あとはもっと内容を充実させていくのみです!