😸

サーフィン用、波情報アプリ開発中~その1~API叩くまで

2024/05/13に公開

はじめに

鹿児島でエンジニアやってますtsurupと言います。私は基本的には毎日朝活で30〜1時間個人開発やってます。また、Noteの方に毎日の朝活の様子を発信しています。今はサーフィン用の波情報取得アプリを開発していてその過程を投稿しています。
一旦キリのいいところまで開発したので、これを機に現在の実装の復習とまとめ記事を書いてみようと思いました。
この記事では波情報を表示するまでの過程を紹介したいと思います。

開発理由

世の中にはすでに波情報アプリは存在します。ただ、こんな機能あるといいなーとか、ここのポイントはアプリにはないなーっとか思っていました。そこで朝活でアプリ作っちゃえばいいじゃん!っと思って作り始めました。

使用技術

  • JavaScript
  • TypeScript
  • React
  • Docker Compose

そんなもんかな?

波情報を取得するAPI

波情報を提供しているAPIを探してみると、いくつかの波情報アプリが提供されていました。
ただ、どれも有料で私のはただ個人開発の遊びみたいなものなので、無料のものを探しました。
https://open-meteo.com/
見つけたのが上記のAPI、商用利用でなければ制限はありますが無料です。詳しく知りたい方は公式をチェックしてください。

リクエストを投げる

早速、波情報を取得するためにAPIに位置情報と必要な情報を指定してリクエストを送ります。
初めに注意していただきたいのはこちらのAPIはライブラリを提供しています。
ただ、私が最初にしっかり確認せずに実装を進めてしまったので直接クエリパラメータくっつけて投げちゃってます!
説明書ちゃんと読まずに使っちゃうタイプです。

エンドポイントはこちら
https://marine-api.open-meteo.com/v1/marine
これにくっつけていきます。
latitude:緯度
longitude:経度
swell_wave_height:うねりの高さ
swell_wave_direction:うねりの向き
timezone=Asia%2FTokyo)

出来上がったのがこちらです。

latitude=31.4033&longitude=131.3417&current=swell_wave_height&hourly=swell_wave_height,swell_wave_direction&timezone=Asia%2FTokyo)

これは私がよく行く恋ヶ浦というポイントの位置情報です。
位置情報はGoogle Mapからとってきています。
レスポンスとかは割愛しますー

リクエストを投げる処理

まず、各ポイントの情報を動的に管理し、コード内で直接書く必要がないように、環境変数.envでポイント情報を管理します。本来はサーバーサイドを実装するべきでしょうが、まだ実装する予定はないので一旦の措置です。

環境変数の設定

環境変数は以下のように設定します:

REACT_APP_KOIGAURA_POINT="恋ヶ浦"
REACT_APP_KOIGAURA_COORDS=31.4033,131.3417
REACT_APP_NISHIKATA_POINT="西方海水浴場"
REACT_APP_NISHIKATA_COORDS=31.911186,130.224127

API リクエスト関数の定義

次に、fetchWaveData.jsファイルで波情報を取得するためのAPIリクエスト関数fetchWaveDataを定義します。この関数では、環境変数からポイント名に基づく座標を取得し、APIのURLを動的に生成します。

export const fetchWaveData = async (point:any): Promise<WaveData | ErrorCode> => {

  const coords = process.env[`REACT_APP_${point.toUpperCase()}_COORDS`] ?? '000,000';

  const [latitude, longitude] = coords.split(',');
  const baseUrl = "https://marine-api.open-meteo.com/v1/marine";

  const params = {
    latitude: latitude,
    longitude: longitude,
    current: "swell_wave_height",
    hourly: ["wave_height", "wave_direction", "wind_wave_height", "wind_wave_direction", "swell_wave_height", "swell_wave_direction"],
    timezone: "Asia%2FTokyo"
  }; //上に載せていないデータも取ってます

const point_api_url = `${baseUrl}?latitude=${params.latitude}&longitude=${params.longitude}&current=${params.current}&hourly=${params.hourly.join(',')}&timezone=${params.timezone}`;

コンポーネントでのデータ取得

最後に、表を表示するReactコンポーネント内でuseEffectフックを使用し、表示したいポイントに基づいてfetchWaveData関数を呼び出します。これにより、ユーザーが選択したポイントの波情報を取得し、表示します。

  useEffect(() => {
    const getOrders = async () => {
      try {
        const waveDataList = await fetchWaveData(point);
        const windsDataList = await fetchWindData(point);
        setWaveData(waveDataList);
        setWindData(windsDataList);
      } catch (error) {
        console.error(error);
      }
    };

    getOrders();
  }, [point]);

このuseEffectフックでは、pointという依存関係を監視しています。pointが変更されるたびにgetOrders関数が再実行され、新しいポイントのデータが取得されて表示されます。これにより、ユーザーがポイントを切り替えた際に、自動的に新しい波情報が表示されるようになります。

おわりに

我ながら文章力のなさに絶望しました。
あまりに酷かったのでChatGPTにほとんど手伝っていただきました。
まだまだ実装している部分もあるのですが、記事のボリュームが増えてきたので、一旦これで区切りたいと思います。

Discussion