0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Route53, GCE, React, FastAPIを用いて簡単なWebアプリを作製する 【中編】

Last updated at Posted at 2021-08-15

なんの記事?

以下の記事の中編にあたります。

手順

残りの手順として

  • フロントエンド
  • 結合
  • デプロイ

が存在します。が、その前に docker-compose でバックエンドとフロントエンドの環境を整えます。

構成

今回は以前にbackendのリポジトリを作成してしまったので、submoduleでバックエンドを引っ張ってきます。

.
├── README.md
├── docker-compose.prod.yml
├── docker-compose.yml
├── backend
│   ├── Dockerfile
│   ├── README.md
│   ├── app
│   ├── backend
│   ├── pytest.ini
│   ├── requirements.dev.txt
│   ├── requirements.txt
│   └── tests
└── frontend
    ├── Docekrfile.prod
    ├── Dockerfile.dev
    ├── README.md
    ├── node_modules
    ├── package.json
    ├── public
    ├── src
    └── yarn.lock

リポジトリは以下になります。

開発環境用のdocker-compose.yml

最終的に以下のようになりました。

docker-compose.yml
services:
    backend:
        tty: true
        build:
            context: ./backend
            dockerfile: Dockerfile
        volumes:
            - ./backend/:/backend/
        command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --log-level trace
        ports:
            - 8000:8000
    frontend:
        build:
            context: ./frontend
            dockerfile: Dockerfile.dev
        command: yarn start
        volumes:
            - ./frontend:/usr/src/app
        ports:
            - "3000:3000"

docker-compose up --buildを行いlocalhost:8000, localhost:3000 を見に行くことで、それぞれ起動していることが確認できます。
また、volumes でマウントを行っているので、docker-compose up --build -d で立ち上げたあと、開発しながら localhost:3000 を見に行くことで、開発を進めることが可能です。
開発を終えるときは docker-compose downをしておきましょう。

本番環境用のdocker-compose.prod.yml

本番環境用ではnginxを用いてフロントが表示されるように変更します。

docker-compose.prod.yml
services:
    backend:
        tty: true
        build:
            context: ./backend
            dockerfile: Dockerfile
        volumes:
            - ./backend/:/backend/
        command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --log-level trace
        ports:
            - 8000:8000
    frontend:
        build:
            context: ./frontend
            dockerfile: Dockerfile.prod
        volumes:
            - ./frontend:/usr/src/app
        ports:
            - "80:80"

本番用のフロントは以下のようになります。

./frontend/Dockerfile.prod
FROM node:latest AS builder
WORKDIR /usr/src/app
COPY . .
RUN npm install
RUN npm run build

FROM nginx:latest
RUN rm -r -f /usr/share/nginx/html
COPY --from=builder /usr/src/app/build /usr/share/nginx/html

nginx経由の表示については、こちらを参考にしました。

docker-compose -f docker-compose.prod.yml up -d --build を行うことで、 localhostでのフロント表示が確認できます。

image.png

フロントエンド実装

フロントエンド実装に移ります。前回実装したAPIから、結果を取得する関数fetchPapers、またpaperをレンダリングするPaperコンポーネントと、Paper一覧を表示するPapersを実装します。

fetchPapers.js
import axios from 'axios';
import DEFAULT_API_LOCALHOST from '../urls';

export const fetchPapers =() => {
    return axios.get(DEFAULT_API_LOCALHOST)
    .then(res => {
      return res.data
    })
    .catch((e) => console.error(e))
  }

DEFAULT_API_LOCALHOST は前回実装したAPIのエンドポイント、すなわちhttp://localhost:8000/api/papers/になります。

index.js
const DEFAULT_API_LOCALHOST = 'http://localhost:8000/api/papers/'

export default DEFAULT_API_LOCALHOST;

仮置で、fetchPapers関数を用いて、APIの結果が帰ってくるかどうかをconsole上で見てみます。

src/pages/Papers.js
import React, { Fragment, useEffect } from 'react';

// apis
import Paper from '../components/Paper';
import { fetchPapers } from '../apis/fetchPapers';

export const Papers = () => {

    useEffect(() => {
        fetchPapers()
        .then((data) =>
        console.log(data)
        )
    }, [])

    return (
        <Fragment>
            Paper一覧
        </Fragment>
    )
}

export default Papers;

トップページでPapersをレンダし、ブラウザ上でログを見てみます。

image.png

NetWorkErrorで怒られてしまっています。networkのログを見てみると

image.png

バックエンド側のCORS設定に問題があるようです。

を参考に、バックエンドを修正します。

backend/app/main.py
import uvicorn
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
from backend.arxiv_api import ArxivApiClass
from backend.extractor import Extractor

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

arxiv_api = ArxivApiClass()
extractor = Extractor()
# ...

submodule側で更新を行い、mainブランチにマージしたので、その反映を行います。

(base) ➜  arxiv-checker git:(feature/createPaperComponent) ✗ git submodule foreach git pull origin main
Entering 'backend'
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 8 (delta 4), reused 7 (delta 4), pack-reused 0
Unpacking objects: 100% (8/8), done.
From github.com:izuna385/arxiv-checker-backend
 * branch            main       -> FETCH_HEAD
   c37561e..6f5d886  main       -> origin/main
Updating c37561e..6f5d886
Fast-forward
 README.md   |  4 ++--
 app/main.py | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)
(base) ➜  arxiv-checker git:(feature/createPaperComponent) ✗ 

docker-compost up --build で再度開発環境をビルドした後、localhost:3000番を見に行きます。

image.png

バックエンドから論文一覧を取得できていることが分かります。

useState, useEffectを用いたレンダリング

バックエンドからの結果を実際にレンダリングする実装を次に行います。

Papers.js
import React, { Fragment, useEffect, useState } from 'react';

// apis
import Paper from '../components/Paper';
import { fetchPapers } from '../apis/fetchPapers';

export const Papers = () => {

    const[allPapersData, setAllPapersData] = useState([]);

    useEffect(() => {
        fetchPapers()
        .then(data => setAllPapersData(data.papers))
    }, [])

    return (
        <Fragment>
            {console.log(allPapersData)}
            <ul>
                {allPapersData.map((data) => (
                    <Paper paperData={data}/>
                ))}
            </ul>
        </Fragment>
    )
}

export default Papers;

allPapersDataを空の初期値で定義し、そこにバックエンドからの結果を格納しています。

ブラウザ上では、バックエンドの返却結果のリストの各要素が、Paperコンポーネントとして表示されます。
image.png

ここまでで、バックエンドとフロントエンドの結合までを完了しました。
動作を確認する場合は、リポジトリからcloneし、docker-compose up --buildで確認可能です。

また、UIの調整についてはここでは省略しますが、今回はreact-bootstrapを用いました。

image.png

次回

リポジトリ

参考文献

React+Docker+DockerComposeの開発環境の構築について説明

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?