進捗
前回の記事から変わった部分はあまりありません。
というより、画面はほとんど実装していません。
今回は、フロントエンドから呼び出すAPIをバックエンドで管理するため、
Laravel 11系を使って環境を作りました。
これを終えると、いよいよログイン認証まわりを作っていこうかと思っています。
(Auth0を使用する予定)
手順
①Laravelプロジェクトを作り、
②テーブルを作成し、
③カールを叩いて疎通確認。
④その後、フロントエンドから呼び出せることを確認して完了
という流れです。
①Laravelプロジェクト作成
※Composer入っていること前提です。
composer create-project --prefer-dist laravel/laravel my-project
②テーブル作成
ローカル環境のDBに接続し、migrationを使ってテーブルを作成します。
まずは.envを自身のローカル環境に設定。
その後、migrationを使って、テーブルを新たに作成。
php artisan make:migration create_tags_table --create=tags // マイグレーションファイルが作成されるのでカラム追加する
php artisan migrate
③カールを叩いて疎通確認
ローカルのサーバーを立ち上げて疎通確認を行う。
php artisan serve // これでサーバが立ち上がり、http://127.0.0.1:8000でリッスンされる
テストコントローラを作成し、GETのAPIを作ってみる。
php artisan make:controller Api/TestController // コントローラーのテストメソッドを一つ作ってみる
別シェルで呼び出してみる(今回はTestControllerにtestというメソッドを作りました)
curl http://localhost:8000/v1/test
{"message":"\u30c6\u30b9\u30c8\u30b3\u30fc\u30c9\u3067\u3059","number":0}
文字列と数値を返すAPIを用意しました。文字列がエスケープしていますが、ちゃんと帰ってくることを確認できます。
④フロントエンドから呼び出せることを確認して完了
いよいよ、フロントエンドからこれを呼び出す準備をします。
まず、APIを呼び出すためにaxiosをインストールします。
npm install axios
ライブラリを追加したら、.envに環境変数を定義します。
REACT_APP_API_URL=http://localhost:8000/v1
REACT_APP_OTHER_VARIABLE=some_value
最後にAPIを呼び出す処理を書き、疎通確認を行います。
(ある程度コード割愛していますし、インデントがずれちゃってます)
import React, { useEffect } from 'react';
import axios from 'axios';
function App() {
useEffect(() => {
const fetchData = async () => {
try {
console.log('API疎通確認');
const res = await axios.get(`${process.env.REACT_APP_API_URL}/test`);
console.log(res);
} catch (e) {
console.error(e);
} finally {
console.log('API疎通完了');
}
};
fetchData();
});
~~~
}
ちゃんとブラウザでAPIレスポンスを取得できることを確認できました!
CORSエラーについて
フロントエンドからバックエンドにAPIをリクエストする際、
オリジンが異なる、すなわち別のリソースへアクセスする場合、
CORSエラーが発生します。
ブラウザはSORS(Same-Origin Resource shareing)という仕組みを実装していて、異なるオリジン(Cross-origin)間へのリソースへのアクセスを制限しています。
なぜ、制限しているかというと、クロスサイトサージェリーなどのセキュリティ攻撃を防止するためです。
で、CORS(Cross-origin resource sharing)が何なのかというと、このSORSの制約を一部解除することで異なるオリジンへのリソースのアクセスを許可したものです。
バックエンドAPIのレスポンスヘッダーに情報を加えることで解決できるようですが、
一時的な解決方法として私は、CORSエラーを無視するChrome拡張機能を使用しました。