【React×FastAPI】axiosでAPIを叩き値を返したいが値は返らずエラーも出ない
概要
React で簡単な SPA を作成し Firebase にデプロイしました.その中で文字列を送信する Form を作成してあります.
バックエンドは FastAPI で作成して Deta という PaaS/BaaS にデプロイしてあります.
フロントエンドとバックエンドが繋げられているかテストするために,Form から文字列が送信されたらバックエンド側で別の文字列を付け足して返す,という処理をしようとしています.
できないこと
Form が送信されると axios がバックエンドの API を叩くようにしようとしていますが,意図通りに動作しません.
Form が送信されバックエンドの API が叩かれている形跡はあるが値が返ってこない上にエラーなども出ていない
やったこと
- フロントはローカルで立ち上げたもので実行してもデプロイしたものから実行しても挙動は同じ
- Form を作成し TextField ( materialUI ) に入力された文字列を送信する
- バックエンドは FastAPI ( Python ) で作成し Deta という PasS / BaaS にデプロイ済み
- エラーメッセージなどは一切でない
- サーバのログには 200 番で成功した旨が表示されている
- Postman や curl で叩くと成功している
環境
- ローカル: MacOSX Big Sur 11.4
- フロントエンド: React
- バックエンド: FastAPI
- サーバ: Deta Micros
背景
React と FastAPI を使ってフロントとバックエンドをつないだアプリ開発の勉強を独学で行っています.ベストプラクティスなどはきちんと把握しておらず基本的には使っている技術のドキュメントに沿って進めています.
デバッグ
- React で Form を作成 ( materialUI の TextField, Button を使用 )
- Form が送信されるとサービスクラスのメソッドが呼ばれる
- このメソッドに axios.get() がある
- axios.get() の前後にある console.log は表示されるが axios.get()に繋げた .then().catch.finally() は動いていない
- デプロイされているサーバのログに実行されたログがあり 200 で正常に動いている
- ログには get で送られてきたデータも入っている上バックエンドの処理も実行されており問題ないように見える
- なので axios.get() 自体は動いているが then() には入らないという状態?
- ブラウザのデベロッパツールでネットワークを確認するもエラーなどは何もない
ソースコード
フロント
- React ( src/screens/Screen.jsx )
import React, { useState, useCallback } from "react"; import EdgeBar from "../components/EdgeBar"; import Box from "@material-ui/core/Box/Box"; import TextField from "@material-ui/core/TextField"; import { makeStyles, Grid, Typography, Button } from "@material-ui/core/"; import ApiTest from "../services/test/apiTest"; // API を叩くためのクラス . . スタイル省略 . const screen = () => { const classes = useStyles(); const [text, setText] = useState(""); // フォームの入力を入れるstate const changeInput = useCallback((event) => { setText(event.target.value); // フォームの入力を取得 }, []); // うまく行かないのはここ const handleSubmit = useCallback(async () => { const response = await ApiTest.getText(text); // API を叩くためのクラス ( apiTest.js へ ) console.log("response: ", response); // 表示される alert("response: " + response); // これが表示されるが }, [text]); return ( <EdgeBar title=""> <Typography className={classes.title}> Credibility Assessment System </Typography> <Typography className={classes.title}>Now in Preparation...</Typography> <Box className={classes.contentArea} p={1} m={1}> <Grid className={classes.paragraph}> <form className={classes.from} onSubmit={handleSubmit} noValidate autoComplete="off" > <TextField className={classes.textField} label="INPUT TEXT" variant="outlined" value={text} onChange={changeInput} /> <Button className={classes.button} type="submit" variant="contained" disableElevation > submit </Button> </form> </Grid> </Box> </EdgeBar> ); }; export default Screen;
- src/services/test/apiTest.js
// テスト用のクラス const axios = require("axios").default; const url = "https://url.dev"; // あっている export default class CredibilityAssessment { static getText(text) { console.log("START"); // 表示される axios .get(`${url}test/${text}`) // PATH もあっている ( サーバのログを見ると実行されている ) .then((res) => { console.log("success: ", res.data); // 表示されないので何故かここには入ってこない return res.data; // 返されない }) .catch((err) => { console.log("failed: ", err); // 表示されない return err; // 返されない }) .finally((res) => { console.log("failed: ", res.data); // 表示されない return res; // 返されない }); console.log("END"); // 表示される return "axios skipped"; // 返される } }
バックエンド
- app/main.py ( Deta にデプロイされている fastapi )
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from services.test import TestClass # Generate FastAPI instance app = FastAPI() # CORSを回避するための設定 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Routing @app.get("/") async def root(): return {"message": "It Works!"} # 動作確認用 @app.get("/test/{text}") async def test(text): res = TestClass.test(text) // test.py へ return {"message": res}
- app/services/test.py
class TestClass: # 動作確認用 def test(text): return "API works! " + text
備考
- react や nodejs, axios, fastapi, Deta はすべて初めて使っています.
- 変数名・関数名などが適当ですみません,サクッと試そうとしたため適当になっています
- 説明のためにコメントをたくさん残しました
- 問題が React なのか JS の書き方なのか FastAPI なのかサーバーの設定なのか,それとも他に何かあるのか,切り分けができていない状態です
公式ドキュメントや Google を活用してあらゆる方法をためしたのですが一日経っても解決しなかったため質問させていただきます.
書き方も then catch ではなく async await にしたり jsx のフォームを変えたりしてみましたがうまく動作しませんでした.
サーバーのログに実行の形跡があるパターンと,そもそも API が叩かれていない時と2パターンあります.
助けていただけると幸いです!
よろしくお願いいたします!
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。