ReactとNode.js(express)でAPIの通信を確立する

## 概要
サーバーを立ち上げてAPIを叩くという一連の流れを確認してみたかったので、ローカルでフロントエンドとしてReact, バックエンドとしてNode.js(express)を立ち上げてAPI（Fetch）叩いてみる。
フロント側としてはわざわざReactでやる意味はないが慣れているため採用しました。

## 1. Node.js(Express)でサーバーを立ち上げる

1. `cd backend`
2.  `yarn init`でpackage.jsonを初期化。色々質問されるけど、とりあえずデフォルトでok 
2.   `yarn add express`でexpressのパッケージをインストール
2.   index.jsをbackend配下に作成する
2.   index.jsは以下のように記述する

```js
const express = require("express");
const app = express();　//express のインスタンス
const port = 3001; // listenするport番号

app.get("/", (req, res) => {
  res.send("Hello World!");
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

```
6. `node index.js`を実行するとこんな感じでlocalhost:3001に立ち上がる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203886/88b43007-3be2-fe3c-405d-ba023e8dd228.png)。

## 2. Reactを立ち上げる
まずは下記コマンドでサクッとReactの環境を作って立ち上げる

```powershell
npx create-react-app frontend
cd frontend
yarn start
```
こんな感じでlocalhost:3000に立ち上がる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203886/8aea4a07-6c1d-2ce2-60f4-fe07af045ac3.png)


ここまででReactとExpressが立ち上がったので、
次はExpressにAPIを用意してReactからをそれを呼び出す.


## 3. ExpressにAPIを用意する（POSTメソッド）

```js
const express = require("express");
const app = express();
const port = 3001;

app.get("/", (req, res) => {
  res.send("Hello World!");
});

app.post("/", function (req, res) {
  res.send("Got a POST request");
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
```

このままだとCORSのエラーが発生するので、下記のようにヘッダー設定の記述を追加。
こうゆうの使ってもできる -> https://expressjs.com/en/resources/middleware/cors.html

```js
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, PUT, PATCH, DELETE, OPTION"
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});
```

さらに、フロント側からリクエストボディで渡されるjson（後述）を受け取るために
`app.use(express.json());`を追記
postの中の処理も以下のように変更。受け取ったボディをそのまま返すだけ。

```js
app.post("/", function (req, res) {
  try {
    res.json(req.body);
  } catch (error) {
    console.error(error);
  }
});
```

index.jsの全体としてはこんな感じ

```js
const express = require("express");
const app = express();
const port = 3001;

// jsonの受け取り
app.use(express.json());

// cors対策
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, PUT, PATCH, DELETE, OPTION"
  );
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  next();
});

app.get("/", (req, res) => {
  res.send("Hello World!");
});

// postの処理
app.post("/", function (req, res) {
  try {
    res.json(req.body); // jsonで返却
  } catch (error) {
    console.error(error);
  }
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
```

## 4. Fetchの作成
App.jsにて以下のようにfetchを記載。

```js
import "./App.css";

function App() {
  const handleClick = async () => {
    await fetch("http://localhost:3001/", {
      method: "POST",
      mode: "cors",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ name: "hoge", email: "ok@sample.com" }),
    })
      .then((response) => response.json())
      .then((data) => console.log(data));
  };
  return (
    <div className="App">
      <button onClick={handleClick}>post</button>
    </div>
  );
}
```

## 5. 実行！
最後に、ExpressとReactをどちらも起動させた状態で
React側に用意したPostボタンを押下すると、コンソールに値が入ってかえってきているのを確認できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1203886/17c5dd77-e63f-286b-4919-8eef94018560.png)




## 参考
https://create-react-app.dev/docs/getting-started/
https://expressjs.com/ja/starter/installing.html
https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch