初学者で初めてAPI通信にて、ポートフォリオを作成しています。
バックエンドとフロントにて別アプリで作成するためのAPI通信が全くわからず、
とりあえずJsonでHelloと渡す簡単なデータの取得ができたので、メモとして残します。
間違った認識や書き方、アドバイスがあれば教えてもらえると嬉しいです。
開発環境
dockerを使用。
docker-composeにて、rails,Next.jsを管理。
Next.js(フロントエンド)
"next": "13.3.0", "react": "18.2.0",
オリジン "http://localhost:8080"
rails(バックエンド)
ruby '3.1.4','rails', '~> 6.1.7', '>= 6.1.7.3'
オリジン "http://localhost:3000"
手順
⚪︎rails
- json形式"Hello"データを渡す、routesの設定。
- gem 'rack-cors'を追加。
- config/initializers/cors.rbにて、corsの設定。
⚪︎Next.js
- axiosを追加。
- axiosにてbaseURLを指定する。
- APIエンドポイントにGETリクエストを送信する関数
- コンポーネントのマウント時にAPIリクエストを送信。
- 取得したデータを表示
Rails
1. json形式データを渡す。
class Api::V1::HelloController < ApplicationController
def index
render json: "hello"
end
end
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get 'hello', to: 'hello#index'
end
end
end
2. gem 'rack-cors'を追加。
コメントになっているので、コメントを解除する。
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
- # gem 'rack-cors'
+ gem 'rack-cors'
Gemfileを更新した際は、buildとbundle install忘れずに!
$ docker-compose build --no-cache
$ docker-compose run --rm (サービス名) bundle install
3. config/initializers/cors.rbにて、corsの設定。
CORS(Cross-Origin Resource Sharing)の設定にて、異なるオリジン(ドメイン・ポート・プロトコルの組み合わせ)からのリクエストを許可する設定を記述。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
# 許可するオリジンの設定
origins 'localhost:8080'
# 全てのリソースに対してCORS設定を適用。
resource '*',
# :anyで全てのリクエストヘッダーを許可する。
headers: :any,
# 許可するHTTPメソッド(GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD)を指定。
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
・リクエストヘッダー(Request Header)
HTTPリクエストに関する、様々なメタ情報を提供し、サーバーがリクエストを処理する情報を提供する。
※参考
基本的なWeb技術に関するまとめ
axiosとrailsのCORS
⚪︎Next.js
1. axiosを追加。
$ docker-compose rum --rm <サービス名> npm install axios
2. axiosのインスタンスを作成。
実際のポートフォリオでは、beseURLをaxiosのインスタンスで作成し、
別ファイルに書いてインスタンスをエクスポートします。
今回はシンプルにindex.jsに全て書いてしまいます。
import axios from "axios";
export default function Hello() {
// Axiosインスタンスを作成して、複数のエンドポイントを設定可能にする。
// baseURLを設定する。
const instance = axios.create({
baseURL: "http://localhost:3000",
});
// APIエンドポイントURL(実際railsからHelloを取得するためのURL)
const apiUrl = "/api/v1/hello";
3. axiosインスタンスを利用し、実際のURLにgetリクエストを送信する関数を作成。
// useStateを使用するので、追加
import { useState } from "react";
~~~~~~~~~~~~~~~
省略
~~~~~~~~~~~~~~~
// 取得したデータを、表示するためにuseStateを使用
const [helloData, setHelloData] = useState("");
// async関数で非同期関数として作成
// getリクエストを送り、データを取得する関数。
const getHello = async () => {
// 非同期関数内では、APIリクエストも非同期に行うため'try-eatch'文を使用
// 非同期処理成功は、'try'ブロック内のコードが実行
// エラーが発生した場合は、'catch'ブロックが実行され、エラーが'error'に格納される
try {
// 'instance.get(apiUrl);':'axios.get(apiUrl)'
// awaitは非同期操作を同期的に扱っているため、'axios.get(apiUrl)'が完了するまで次のコードが実行されません。
// 'axios.get(apiUrl)'は、getリクエストを送信し、サーバーからのレスポンスを取得
const response = await instance.get(apiUrl);
setHelloData(response.data);
} catch (error) {
console.error(error);
}
};
4. コンポーネントのマウント時にAPIリクエストを送信。
// コンポーネントがマウント時に一度だけ実行される。
useEffect(() => {
getHello();
}, []);
5. 取得したデータを表示
import { useState, useEffect } from "react";
import axios from "axios";
export default function Hello() {
const instance = axios.create({
baseURL: "http://localhost:3000",
});
// APIエンドポイントのURL
const apiUrl = "/api/v1/hello"; // 実際のURLに置き換えてください
const [helloData, setHelloData] = useState("");
// APIエンドポイントにGETリクエストを送信する関数
const getHello = async () => {
try {
const response = await instance.get(apiUrl);
setHelloData(response.data);
} catch (error) {
console.error(error);
}
};
// コンポーネントのマウント時にAPIリクエストを送信
useEffect(() => {
getHello();
}, []);
return (
+ <div>
+ <h1>Response: {helloData}</h1>
+ </div>
);
}
※参照
axiosとrailsのCORS
非同期処理やAPIについては以下をとても参考にしました。
WebAPIについての説明
何となくの雰囲気がわかるように、参考になると嬉しいです。
また、間違っている部分などあればご指摘いただけると嬉しいですし、
これ勉強したほうがいいよ!とかも教えてもらえると嬉しいです。