フロントエンドとバックエンドのホスティング方法は?

Back4app フルスタックアプリケーションデプロイカバー

このチュートリアルでは、アプリケーションのフロントエンドとバックエンドをホスティングするための包括的なガイドを提供します。

この目的のために、Back4appでフルスタックアプリをホストする。最初にバックエンドに取り組み、次にフロントエンドに移り、最後に2つのコンポーネントを接続する。

目標

この記事を読み終わる頃には、あなたはこうなっているはずだ:

フロントエンドとバックエンドの違いは何ですか?

バックエンドとフロントエンドとは、最新のウェブアプリケーションやモバイルアプリケーションを構築する際の関心事の分離を指す。その違いを理解する最も簡単な方法は、氷山を視覚化することだ。

バックエンドとフロントエンド

フロントエンド(またはクライアントサイド)とは、ユーザーが見ることができ、対話することができるすべてのものである。フロントエンドは、モバイルアプリケーション、ウェブアプリケーション、ウェブインターフェイス、またはその他のタイプのクライアントなど、さまざまな形式で提供されます。

このアプリケーションパートは、UI/UX、デザイン、アニメーション、グラフィック、その他のメディアタイプを担当します。クライアントサイドはプロジェクト作業の20%を占め、重複はありません。

一方、バックエンド(またはサーバーサイド)は、ユーザーが見ることのできないすべてのものです。フロントエンドとデータベースの橋渡し役だ。

ビジネスロジック、バックグラウンドタスク、データストレージ、スケーリング、サードパーティの統合などを担当する。ユーザーが直接操作できなくても、アプリケーションの品質に大きな影響を与えます。

プロジェクト作業の約80%を占め、ユーザー管理、認証、暗号化などの反復作業が含まれることが多い。

このチュートリアルでは、フロントエンドとバックエンドを無料でBack4appにデプロイする方法を学びます!バックエンドとフロントエンドをデプロイする方法を学びましょう。

プロジェクト紹介

Back4appにフロントエンドとバックエンドをデプロイする方法を示すために、フルスタックのアプリケーションを用意した。

このアプリはシンプルなマークダウンブログとして機能する。管理者は記事の追加、編集、削除ができ、ユーザーは記事を読むことができる。

最終的なプロジェクトはこんな感じになるだろう:

Back4app フルスタックアプリブログ

前述したように、アプリはフロントエンドとバックエンドの2つの部分で構成されている。アプリのアーキテクチャを視覚化すると、次のようになる:

Back4app フルスタック・アプリケーション・アーキテクチャ

バックエンドはBack4 appに、フロントエンドアプリはBack4app Containersにデプロイします。最後に、Parse SDKを使って2つのコンポーネントを接続する。

まずはこのアプリを使い、後でフルスタックのアプリケーションをデプロイして知識を試すことをお勧めする。

バックエンドとフロントエンドのホスティング方法については、このまま読み進めてください。

バックエンドのホスティング方法は?

このセクションでは、アプリケーションのバックエンド部分を扱います。

目的

  1. Back4appアプリケーションをビルドする
  2. データベースクラスの定義
  3. データベースACL/CLPの設定
  4. データベースへの入力
  5. 管理者アプリを有効にする

Back4appアプリの作成

フォローするには無料のBack4appアカウントが必要です。まだ登録されていない方は、無料登録してください!

Back4appを使うには、まずアプリケーションを作成する必要があります。Back4appで認証すると、アプリビューにリダイレクトされます。Build new app “ボタンをクリックしてください。

Back4app アプリ作成

次に、バックエンドをデプロイするので、”Backend as a Service “を選択する。

Back4app Backend as a Service

アプリに名前を付け、”NoSQL “データベースを選択し、”Create “をクリックする。

Back4app BaaSの構成

プラットフォームは、すべての準備(データベース、スケーリング、バックアップ、アプリケーションレイヤーなど)に少し時間がかかります。その間、コーヒーでも飲んで休憩してください。

アプリの準備ができたら、データベース・エクスプローラーが表示されます。

Back4appデータベースビュー

データベースの定義

このセクションでは、データベース・クラスについて説明します。

シンプルなアプリケーションを作るので、必要なクラスは1つだけです。サイドバーの “Create a class “をクリックし、名前をArticleとし、他はデフォルトのままにして、”Create class & add columns “をクリックします。

Back4app データベース作成クラス

そこに以下の5つの列を追加する:

+-----------+--------------+----------------+----------+
| Data type | Name         | Default value  | Required |
+-----------+--------------+----------------+----------+
| String    | slug         | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | title        | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| File      | cover        | <leave blank>  | 0        |
+-----------+--------------+----------------+----------+
| String    | shortContent | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+
| String    | content      | <leave blank>  | 1        |
+-----------+--------------+----------------+----------+

保存したい追加データの列を追加してください。

デフォルトでは、データベース・クラスは “保護モード “になっています。フロントエンド・アプリからデータベース・クラスを操作したい場合は、クラス・レベルのパーミッション(CLP)を少し変更する必要があります。画面上部のロックアイコンをクリックし、CLPを以下のように変更してください:

Back4appクラスCLP

パース・セキュリティの詳細については、以下の記事をご覧ください。

最後に、いくつかのサンプル記事をデータベースに登録する。

心当たりがない場合は、このデータベース・ダンプをインポートしてください。インポートするには、画面右上のその他のオプションをクリックし、「インポート > クラスデータ」をクリックし、JSONをインポートする。

Back4appデータベースへの登録

素晴らしい!

これでいくつかのテストデータができた。

管理者アプリ

現在、記事を管理する唯一の方法は、Back4appのデータベースビューを使うことです。Back4appの認証情報を共有したり、技術者以外の人をBack4appのダッシュボードに追加したりしたくないので、これは最適ではありません。

幸いなことに、Back4appにはデータベースモデル用の動的な管理インターフェイスが用意されています。これを有効にするには、サイドバーの “More > Admin App “を選択し、”Enable Admin App “をクリックしてください。

Back4app 管理者アプリを有効にする

ユーザー名、パスワード、管理アプリのサブドメインを選びます。私はこうする:

username:     admin
password:     verystrongpassword123
admin url:    https://fullstack.admin.back4app.com/

これで、選択した管理用URLから管理パネルにアクセスできるようになります。

新しいタブを開き、管理パネルに移動します。認証情報を使ってログインし、インターフェイスを探索してください。記事を作成し、更新し、削除することができます。

Back4app Adminアプリのダッシュボード

Back4appの管理者アプリについて、詳しくはドキュメントをご覧ください。

コードなしで本格的なバックエンドを作ることに成功した。

フロントエンドをホスティングするには?

このセクションでは、フロントエンドのアプリを扱う。

目的

  1. ローカル開発環境のセットアップ
  2. アプリケーションをDocker化する
  3. ローカルでDockerイメージをテストする
  4. ソースコードをGitHubにプッシュする
  5. アプリケーションをBack4app Containersにデプロイする

ローカル・セットアップ

このリポジトリのすべてのブランチをフォークし、そのフォークをローカルマシンにクローンすることから始める:

$ git clone <fork_remote_git_url> --branch dummy
$ cd back4app-heroku-deploy && git branch -m master

ダミーブランチをクローンしたのは、バックエンドのコードが含まれていないからです。バックエンドのコードについては次のセクションで説明します。

次に、プロジェクトの依存関係をインストールする:

$ npm install

最後に、開発サーバーを起動する:

$ npm run dev

お気に入りのウェブブラウザを開き、http://localhost:3000。ブログのインデックスページが表示されるはずです。記事をクリックして、記事の詳細ページにリダイレクトされるかどうか試してみてください。

今のところ、記事の詳細ページはハードコーディングされています。後で修正しますのでご心配なく。

ドッカライズ

アプリをBack4app Containersにデプロイするには、まずアプリをDocker化する必要があります。

Docker化とは、どこでもデプロイ可能なコンテナにコードをパッケージ化するプロセスだ。アプリケーションをDocker化する最も簡単な方法は、Dockerfileを使うことだ。

ドッカーファイル

Dockerfileスクリプトには、Dockerコンテナイメージを作成するための指示が含まれています。このファイルを使用して、環境を定義し、依存関係をインストールし、アプリケーションのビルドと実行に必要なコマンドを実行することができます。

プロジェクト・ルートに以下の内容のDockerfileを作成する:

# Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .

RUN npm run build
RUN npm install -g next

EXPOSE 3000

CMD ["next", "start", "-p", "3000"]

このDockerfileは node:18-alpineイメージに基づいています。作業ディレクトリを設定し、依存関係を処理し、プロジェクトをコピーし、アプリをビルドします。

アプリがビルドされると、ポート3000が公開され、そのポートをリッスンするNext.jsサーバーが起動します。

Dockerfileの詳細については、公式ドキュメントをご覧ください。

.dockerignore

Dockerイメージのサイズは最小限に抑えるべきです。Dockerイメージのサイズを小さくする最も簡単な方法は、.dockerignoreファイルを作成することです。このファイルで、最終イメージから除外するファイルやフォルダを指定できます。

例えば、IDEファイル、build.gitnode_modulesをイメージに含めたくありません。

以下は.dockerignoreファイルの例です:

# .dockerignore

.idea/

/node_modules
/.next/
/out/
/build

.vercel

必要に応じて.dockerignoreファイルを変更してください。

ビルド、実行、テスト

Dockerプロジェクトをクラウドにプッシュする前に、ローカルでテストするのは常に良いアイデアです。Dockerファイルをテストする最も簡単な方法は、Docker Desktopをインストールすることです。

インストールしたら、イメージを構築することができる:

$ docker build -t blog-frontend:1.0 .

画像が正常に作成されたかどうかを確認するために画像を一覧表示します:

$ docker images

REPOSITORY        TAG       IMAGE ID       CREATED             SIZE
blog-frontend     1.0       d361534a68da   2 minutes ago       1.08GB

ビルドしたばかりのイメージを使ってコンテナを実行する:

$ docker run -p 3000:3000 --name blog-frontend blog-frontend:1.0

お気に入りのウェブブラウザを開き、http://localhost:3000。アプリがそこにあるはずです!

コンテナを終了するには、キーボードのCTRL + cを押します。

GitHubにプッシュする

Back4pp ContainersはGitHubと緊密に統合されています。コミットごとにアプリを再デプロイする自動CI/CDシステムを提供します。次のセクションでコードをデプロイするには、まず変更をVCSにプッシュする必要があります。

すべての変更をコミットし、クラウドにプッシュする:

$ git add .
$ git commit -m "dockerized the application"
$ git push origin master

GitHubのリポジトリに移動し、Dockerfileがリポジトリに存在することを確認する。

アプリのデプロイ

フォローするには無料のBack4appアカウントが必要です。まだ登録されていない方は、無料登録してください!

まずはBack4appのダッシュボードに移動し、”Build new app “をクリックしてください。

Back4app アプリケーションの作成

Docker化されたアプリケーションをデプロイするので、”Containers as a Service “を選択する。

Back4app Select CaaS

初めてBack4app Containersを使う場合は、GitHubアカウントとBack4appアカウントの接続を求められます。デプロイしたい全てのリポジトリへのアクセスを有効にしてください。

次に、back4app-full-stackリポジトリを見つけ、”Select “をクリックして選択する。

Back4app Select GitHubリポジトリ

今回デプロイするアプリケーションは、特別な設定を必要としない。説明的な “アプリ名 “を指定するだけだ。整理整頓のためにback4app-full-stackとする。

最後に “Deploy “をクリックする。

Back4appコンテナ環境

Back4app Containersは、Dockerイメージのビルドとデプロイに数分かかります。デプロイに成功すると、アプリのステータスが “Ready “に変わります。

アプリケーションにアクセスするには、下の画像に示すように緑色のURLをクリックしてください。

Back4appの導入成功

これで、ダミーのフロントエンドアプリをBack4app Containersにデプロイできました。

フロントエンドとバックエンドの接続方法

このセクションでは、フロントエンドとBack4appバックエンドを接続する。

目的

  1. Parse SDKのインストール
  2. パースSDKの設定
  3. データの取得(ParseQueryなど)

Parse SDKのインストール

まず、Parse SDKをインストールします:

$ npm install parse

パースSDKの設定

Parse SDKを初期化するには、Back4appの “アプリケーションID “と “JavaScriptキー “が必要です。これらを取得するには、Back4appアプリケーションに移動し、サイドバーの “App Settings > Security & Keys “を選択してください。

ソースコードにこれらの秘密を公開したくないので、.env.localファイルを作成する:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<your_parse_app_id>
NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY=<your_parse_js_key>

プレースホルダーを実際の値に置き換えてください。

パースSDKの初期化

次に、providers.jsに移動し、次のようにParseを初期化する:

// src/app/providers.js

// ...

import Parse from "parse/dist/parse";

const PARSE_APPLICATION_ID = process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID;
const PARSE_JAVASCRIPT_KEY = process.env.NEXT_PUBLIC_PARSE_JAVASCRIPT_KEY;
Parse.initialize(PARSE_APPLICATION_ID, PARSE_JAVASCRIPT_KEY);
Parse.serverURL = "https://parseapi.back4app.com/";

export function Providers({children}) {
    return (
        // ...
    );
}

すべてのビューでParseインスタンスにアクセスできるようにする。Reactのコンテキストを使おう。

context/parseContext.jsという名前のファイルを新規作成し、以下のコードを貼り付ける:

// src/app/context/parseContext.js

"use client";

import {createContext} from "react";

const ParseContext = createContext();

export default ParseContext;

次に、アプリ全体をParseContextでラップし、ParseインスタンスをParseContextに渡す:

// src/app/providers.js

// ...

import ParseContext from "@/app/context/parseContext";

export function Providers({children}) {
  return (
    <CacheProvider>
      <ColorModeScript initialColorMode={theme.config.initialColorMode} />
      <ChakraProvider theme={theme}>
        <ParseContext.Provider value={Parse}>
          {children}
        </ParseContext.Provider>
      </ChakraProvider>
    </CacheProvider>
  );
}

これで完了だ!これで、useContext()フックを使って Parse インスタンスにアクセスできるようになりました。

データ取得

最後にしなければならないのは、バックエンドからデータをフェッチすることだ。そのためには、Parse.Queryを使います。このクラスは基本的に Parse ベースのデータベース用の ORM です。

まず、src/app/page.jsxを以下のように置き換える:

// src/app/page.jsx

"use client";

import NextLink from "next/link";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Link, Spinner, Stack, Text} from "@chakra-ui/react";

export default function Home() {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [articles, setArticles] = useState([]);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.descending("createdAt");
        const articles = await query.find();
        setArticles(articles);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      <Stack>
        {articles.map((article) => (
          <Card key={article.get("slug")}>
            <CardBody>
              <Stack>
                <Heading size="lg">
                  <Link as={NextLink} href={article.get("slug")}>
                    {article.get("title")}
                  </Link>
                </Heading>
                <Text>{article.get("shortContent")}</Text>
              </Stack>
            </CardBody>
          </Card>
        ))}
      </Stack>
    </>
  );
}
  1. useContext()フックでParseインスタンスを取得した。
  2. ローディングエラー記事など、いくつかの状態を作った。
  3. ページが開かれたときにParse.Queryを実行するためにuseEffect()フックを使用しました。
  4. Parse.QueryはcreatedAtで並べられたすべての記事をフェッチする。
  5. データをレンダリングするためにreturn文を修正した。

その後、src/app/[slug]/page.jsを次のように置き換える:

// src/app/[slug]/page.js

"use client";

import {formatDate} from "@/app/util/date-util";
import {useContext, useEffect, useState} from "react";
import ParseContext from "@/app/context/parseContext";
import {Card, CardBody, Heading, Image, Spinner, Stack, Text} from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";

export default function Article({params}) {

  const parse = useContext(ParseContext);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [article, setArticle] = useState(null);

  useEffect(() => {
    (async () => {
      try {
        const query = new parse.Query("Article");
        query.equalTo("slug", params.slug);
        const article = await query.first();
        if (!article) {
          setError("This article does not exist.");
        } else {
          setArticle(article);
        }
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    })();
  }, [params.slug, parse.Query]);

  if (loading) {
    return <Spinner size="lg"/>;
  }

  if (error) {
    return <Text color="red">{error}</Text>;
  }

  return (
    <>
      {article && (
        <Stack>
          <Card>
            <CardBody>
              <Stack>
                <Heading as="h2" size="lg">{article.get("title")}</Heading>
                <Text>Posted on {formatDate(article.get("createdAt"))}</Text>
                {article.get("cover") && (
                  <Image 
                      src={article.get("cover").url()} 
                      alt={`${article.get("title")} cover`} 
                      borderRadius="lg"
                  />
                )}
                <ReactMarkdown 
                    components={ChakraUIRenderer()} 
                    children={article.get("content")} 
                    skipHtml
                />
              </Stack>
            </CardBody>
          </Card>
        </Stack>
      )}
    </>
  );
}

上のコードと同じような概念を使っています。2つのコードスニペットの主な違いは、このコードではすべての記事の代わりに特定の記事をフェッチしていることです。

これで完了だ!このプロジェクトをローカルでテストしてみよう:

$ next dev

すべてが機能していることを確認したら、VCSにプッシュする:

$ git add .
$ git commit -m "connected the frontend with the backend"
$ git push origin master

Back4app Containersは、最新の変更を加えたアプリケーションを自動的に再デプロイします。

結論

最後に、私たちはBack4appにフルスタックアプリをデプロイすることに成功しました。このプロセスを通して、アプリケーションのフロントエンドとバックエンドのホスティングに関する貴重な経験を得ることができた。これで自分のフルスタックアプリをデプロイするのに問題はないはずだ。

最終的なソースコードはback4app-full-stackrepoで入手可能で、フロントエンドとバックエンドをどこでホストするかを学んだ。


Leave a reply

Your email address will not be published.