さくらのVPSを使ってシステム開発に必要な知識を学ぶ 〜第13回〜
はじめに
本連載は、システム開発に必要な知識を得るために、一通りの流れを学ぶことを目指しています。
本連載の第7回からは、実際の業務を想定したメモアプリを例に、開発の流れを解説しています。前回はアプリケーションサーバー(APサーバー)とデータベースサーバー(DBサーバー)の通信や、Rustで開発したバックエンド部分について解説しました。今回は主にフロントエンド部分を解説します。
フロントエンド開発の考え方
これまでの本連載で、Webサーバー・APサーバー・DBサーバーを構築してきました。システムの最終形は下図のようになります。
フロントエンドのアプリケーションは、プログラムがどこに置かれているかという意味では上図のようにWebサーバーに設置されています。そして、フロントエンドの開発は、実務では自分のPCで行うことが一般的です。
上記のような開発作業を行う際に、CORSエラーと呼ばれる問題が起きることがあります。
CORSエラーについて
CORSエラーとは
CORS(Cross-Origin Resource Sharing)エラーは、Web開発でよく見られる問題の1つです。これは、ブラウザがセキュリティ上の理由から、異なるオリジン(異なるドメイン、プロトコル、またはポート)からのリクエストに制限を設ける仕組みです。
例えば、あなたのWebサイト(example.com)から別のWebサイト(anotherdomain.com)にリクエストを送信しようとすると、ブラウザはセキュリティ上の理由からこれをブロックします。これは、anotherdomain.comのデータを扱う際にセキュリティリスクがあるためです。
今回の場合、本番用WebサーバーはさくらのVPSにありますが、フロントエンド開発用のWebサーバーを自分のPC内に設置して作業します。このような構成を取る場合、CORSエラーが発生することがあります。
CORSエラーについてのさらに詳しい解説は、こちらのページをご覧ください。
CORSエラー対策
この制約を回避する方法の1つがCORSです。サーバー側でCORSの設定を行うことで、ブラウザがリクエストを許可するようにします。これには、レスポンスヘッダーにAccess-Control-Allow-OriginやAccess-Control-Allow-Methodsを追加するなどの手順が含まれます。
重要な設定は、nginxの /etc/nginx/sites-available/default を修正することです。さくらのVPSに構築したWebサーバーにログインし、
$ sudo vi /etc/nginx/sites-available/default
でファイルを開き、下記の内容を追記して保存してください。
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
(中略)
# 追記箇所 ---------------------------------------
location /api {
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://127.0.0.1:8080; # APIサーバーのポート
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 追記箇所 ---------------------------------------
}
(後略)
保存したら、下記のコマンドを実行してnginxを再起動します。
$ sudo systemctl restart nginx
ローカルでのフロントエンド開発の準備
ローカル環境(ご自身のPC)でフロントエンド開発を始めるための準備をします。作業項目としては以下を行います。
- Node.jsのインストール
- GitHubからソースコードを入手
- ソースコードから呼び出されているライブラリのインストール
Node.jsのインストール
はじめにNode.jsをインストールします。Windowsユーザの方はインストーラーを使ってください。Linuxユーザの方はコマンドラインでインストールします。Macユーザの方はどちらも利用可能です。
インストーラーを使う場合(Windows/macOS)
まずNode.jsのダウンロードページにアクセスします。するとダウンロード画面が表示されます。
Windowsの場合
Windowsユーザの方は以下のように設定してダウンロードボタンを押してください。
- Node.jsのバージョン: 現在表示されているバージョン(通常は最新版)
- OS: Windows
- running(CPUの種別)
- 32bit OSの場合:x86
- 64bit OSの場合:x64
macOSの場合
Macユーザの方は以下のように設定してダウンロードボタンを押してください。
- Node.jsのバージョン: 現在表示されているバージョン(通常は最新版)
- OS: macOS
- running
- Intel CPUの場合:x64
- Apple Silicon(M1,M2,M3)の場合:ARM64
インストール作業
ここではWindows版のみ説明します。下記の画像に沿って作業してください。
インストーラを起動すると下の画面が表示されます。
Nextを押すとライセンス画面が表示されます。「I accept the terms in the License Agreement」にチェックを入れてNextを押します。
インストール先のフォルダを指定します。通常はデフォルトのままで結構です。
インストール内容のカスタマイズ画面です。ここも通常はデフォルトのままNextを押してください。
次はネイティブ拡張の開発に必要なツール類のインストールに関する画面です。ここもデフォルトのままNextを押します。
これでインストールの準備が完了したのでInstallボタンを押します。
ユーザーアカウント制御の画面が出てきますが、「いいえ」のまま次に進みます。
これでインストールが完了となります。Finishを押して終了します。
コマンドでインストールする場合(macOS)
macOSではHomebrewというパッケージ管理システムを使うことで、アップルが提供していないソフトウェアをインストールして利用することができます。ここではHomebrewを使ってNode.jsをインストールします。
Homebrewがインストールされていない場合は、まず下記のコマンドでHomebrewをインストールします。
$ curl -L git.io/nodebrew | perl - setup
その後、brewコマンドにてnodebrewをインストールします。nodebrewは、Node.jsのバージョンを管理するツールです。
$ brew install nodebrew
インストールが完了したら、環境設定ファイル(.zshrc)のPATHにnodebrewのディレクトリを追加し、設定を反映させます。
$ echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.zshrc
$ source ~/.zshrc
インストールしたnodebrewのバージョンを確認します。
$ nodebrew --version
nodebrew 1.1.0 # インストールした時のバージョンになります。
Usage:
nodebrew help Show this message
nodebrew install <version> Download and install <version> (from binary)
nodebrew compile <version> Download and install <version> (from source)
nodebrew install-binary <version> Alias of `install` (For backward compatibility)
nodebrew uninstall <version> Uninstall <version>
nodebrew use <version> Use <version>
nodebrew list List installed versions
nodebrew ls Alias for `list`
nodebrew ls-remote List remote versions
nodebrew ls-all List remote and installed versions
nodebrew alias <key> <value> Set alias
nodebrew unalias <key> Remove alias
nodebrew clean <version> | all Remove source file
nodebrew selfupdate Update nodebrew
nodebrew migrate-package <version> Install global NPM packages contained in <version> to current version
nodebrew exec <version> -- <command> Execute <command> using specified <version>
Example:
# install
nodebrew install v8.9.4
# use a specific version number
nodebrew use v8.9.4
$
nodebrewではインストール可能なNode.jsのバージョン一覧を確認できます。以下は実行例です。
$ nodebrew ls-remote
................ # 中略
v20.0.0 v20.1.0 v20.2.0 v20.3.0 v20.3.1 v20.4.0 v20.5.0 v20.5.1
v20.6.0 v20.6.1 v20.7.0 v20.8.0 v20.8.1 v20.9.0 v20.10.0 v20.11.0
v20.11.1 v20.12.0 v20.12.1
................ # 中略
io@v3.0.0 io@v3.1.0 io@v3.2.0 io@v3.3.0 io@v3.3.1
nodebrewコマンドにてNode.jsをインストールします。
$ nodebrew install v20.12.1
同じくnodebrewコマンドで、使用するNode.jsのバージョンを指定します。先ほどインストールしたバージョンと同じものを指定してください。
$ nodebrew use v20.12.1
コマンドでインストールする場合(Linux)
ここではUbuntuにおける例を紹介します。インストール手順はWelcome to Node.js DEB repositoryを参考にしています。以下のコマンドを実行してください。
$ sudo apt-get -y update # Ubuntuの更新ファイルを入手します。
$ sudo apt-get -y upgrade # Ubuntuを最新の状態に更新します。(省略可)
$ curl -sL https://deb.nodesource.com/setup_20.x | sudo -E bash - # Node.js v20.xを取得します。
$ sudo apt-get install nodejs -y # Node.jsをインストールします。
$ sudo apt-get -y autoremove # Ubuntuの不要パッケージを削除します。(省略可)
$ sudo apt-get -y autoclean # Ubuntuの不要ファイルをクリーニングします。(省略可)
インストール後の確認(Windows/macOS/Linux)
Node.jsのインストールが完了したら、以下のコマンドでバージョンを確認します。npmは、Node.jsのパッケージ管理コマンドです。
$ npm -v
10.5.0
$ node -v
v20.12.1
GitHubからソースコードを入手
今回開発しているアプリのソースコードをGitHubに収録しています。それを入手します。
まずGitHubにログインします。ログインしたら、今回開発しているアプリのソースコードを収録しているdev-ops-sampleというリポジトリがありますので、そちらにアクセスし、これをフォークします。
フォークの操作方法としては、まず画面右上の「Fork」ボタンを押します。
次に、フォーク先のユーザ(Owner)とリポジトリ名を設定します。例えばここでは、Ownerをご自身のGitHubアカウント、リポジトリ名はサンプルと同じくdev-ops-sampleとします。
フォークに成功すると、リポジトリの内容がフォーク先にコピーされます。この状態でフォーク先に対してgit cloneすることによりソースコードをダウンロードします。git cloneのコマンド例を以下に示します。
$ cd work
$ git clone git@github.com:gurezo/dev-ops-sample.git
Cloning into 'dev-ops-sample'...
remote: Enumerating objects: 454, done.
remote: Counting objects: 100% (136/136), done.
remote: Compressing objects: 100% (81/81), done.
remote: Total 454 (delta 71), reused 97 (delta 53), pack-reused 318
Receiving objects: 100% (454/454), 317.04 KiB | 723.00 KiB/s, done.
Resolving deltas: 100% (244/244), done.
リポジトリのディレクトリの解説
git cloneで入手したソースコードは以下のようなディレクトリ構成になっています。package.jsonファイルの説明に出てくるnpm workspacesについてはこちらをご覧ください。
.
├── README.md
├── backend # バックエンドのコードのディレクトリ
├── frontend # フロントエンドのコードのディレクトリ
├── package-lock.json # ライブラリの依存関係が記載されている JSON
└── package.json # npm workspaces を使って作成した時に出来るライブラリ情報が含まれた JSON
3587 directories, 26878 files
このうち、backendディレクトリは以下のような構成になっています。詳細は、さくらのVPSを使ってシステム開発に必要な知識を学ぶ 〜第12回〜を参照してください。
├── backend
│ ├── my_actix_app # AP サーバーに関するコード
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── main.rs
│ └── package.json # このリポジトリにバックエンド用のディレクトリを生成した時に作成されたファイル
.....
なお、今回はバックエンドのコードとフロントエンドのコードを同時に管理するために、Monorepo(モノレポ)と呼ばれる方法でリポジトリを作成しています。Monorepoとは、アプリケーションやマイクロサービスの全コードを単一のリポジトリに保存するやり方のことです。
frontendディレクトリ以下の解説は後述します。
アプリで使用するライブラリのインストール
git cloneしたリポジトリのディレクトリに移動し、npm installを実行して、アプリを動かすのに必要なライブラリ(主にフロントエンド用)をインストールします。実行例を以下に示します。
$ cd dev-ops-sample
$ npm i
added 972 packages, and audited 975 packages in 19s
117 packages are looking for funding
run `npm fund` for details
3 vulnerabilities (2 moderate, 1 high)
To address all issues, run:
npm audit fix
Run `npm audit` for details.
➜ dev-ops-sample git:(main) ✗
SPAについて
SPAとは
SPA(単一ページアプリケーション/Single Page Application)はWebアプリの実装の一種です。単一のWeb文書のみを読み込み、別な内容を表示する際にはXMLHttpRequestやFetchなどのJavaScript APIを通じて単一文書の本文の内容を更新するものです。Webサイトに公開するのは1つのHTMLファイル(単一ページ)となります。
SPAを採用することで、サーバーから新しいページ全体を読み込むことなく、ユーザーにWebサイトを使わせることができます。これにより性能の向上やより動的な利用方法を得ることができます。
しかしそれと引き換えに、SEOなどで不利になったり、状態の保守、操作の改善、意味のある性能の監視のためにより労力が必要になったりします。
なお、SPAの対義語としてMPA(Multi Page Application)があります。初歩的なホームページ作成などで紹介されるサイトマップはMPAに当たります。例えば下図は、ある会社のホームページのサイトマップです。このように複数のHTMLファイルで構成されるのがMPAです。
.
├── index.html # トップページ
├── product.html # 製品情報のページ
├── contact.html # 連絡フォームのページ
└── company.html # 会社概要のページ
SPAに関するさらに詳しい情報はこちらをご覧ください。
SPAの開発で使われるフレームワーク
SPAの開発で使われるフレームワークとしては、Angular、React、Vue.jsなどがあります。クライアントサイドのJavaScriptフレームワークについては、「クライアントサイドのJavaScriptフレームワークを理解する」という文書で詳しく解説されていますのでご覧ください。
Angularの紹介
今回のフロントエンド開発では、フレームワークとしてAngular(アンギュラー)を使用します。AngularはTypeScript (マイクロソフトが開発した、JavaScriptを拡張した言語)ベースのフロントエンドWebアプリケーションフレームワークです。GoogleのAngularチームと個人や企業のコミュニティによって、オープンソースソフトウェアとして開発されています。
Angularの特徴としては以下が挙げられます。
- SPAの開発に適しています。
- コンポーネント指向アーキテクチャです。コンポーネントの概念などは後述します。
- フルスタックフレームワークであり、フロントエンド開発に必要な機能が一通りそろっています。ここでいうフルスタック(full-stack)とは、複数の分野の技術が含まれていることを意味します。Angularを使いこなすには、Web、TypeScript、ユニットテスト、E2E(End to End)テストなどの技術や知識が必要になります。
Angularに関するさらに詳しい情報は、公式サイトをご覧ください。なお、従来提供されてきた日本語版公式ページに代わって、新しい公式ページ(現在はBETAドキュメント)が公開されています。
Angularで使われるファイル
Angularでは、画面そのものや画面の部品の単位をコンポーネント(component)と呼びます。AngularではngコマンドというCLIが使えますが、それを用いて画面および画面用部品を生成します。生成されるファイルは下記の通りです。(xxxxはコンポーネント名です)
xxxx.component.html
- 画面や画面の部品を表示するファイルです。
- HTMLで書かれたxxxxコンポーネントのテンプレートです。
- コンポーネント用のHTMLをテンプレートと表現します。
xxxx.component.css/scss
- 画面や画面の部品を装飾するファイルです。
- xxxxコンポーネント専用のCSSです。
- 装飾のスタイルとして、Angularでは以下のものが使用可能です。
xxxx.component.ts
- 画面や画面の部品を制御するファイルです。
- TypeScriptで書かれたプログラムを実装します。
xxxx.component.spec.ts
- 画面や画面の部品の(ユニット)テストを行うファイルです。
- xxxx.component.tsのテストファイルがxxxx.component.spec.tsです。
- Angularでは、テストファイルの拡張子に通常
spec.ts
を付けます。 - デフォルトで作成されるテストは、下記のライブラリで実行されます。
- Karma
- ブラウザでテストを実行するプログラム(テストランナー)です。
- Jasmine
- JavaScript用のテスティングフレームワークです。
- 最近のプロダクトでは、JavaScriptのテスティングフレームワークにjestを使うことがトレンドになっています。
xxxx.service.ts
- 主に画面操作やAPIの実行など、画面や画面部品の制御プログラムを実装するファイルです。
- TypeScriptで書かれたプログラムを実装します。
xxxx.service.spec.ts
- xxxx.service.tsのテストを行うファイルです。
- 画面や画面部品の制御プログラムのテストを行います。
- TypeScriptで書かれたプログラムを実装します。
フロントエンドの実装
ここからはフロントエンド開発において作成したコードを紹介します。
フロントエンドのディレクトリ構成
git cloneで入手したdev-ops-sampleというリポジトリのうち、frontend以下のディレクトリおよび各ファイルの構成を以下に示します。
なお、frontend/src/app/shared/models/index.ts の説明にある「バレルファイル」とは、Typescriptにおいて、複数のモジュールから1つの便利なモジュールにエクスポートをロールアップするファイルです。詳しくはバレルの解説ページをご覧ください。
├── frontend
│ ├── README.md
│ ├── angular.json # Angular プロジェクト情報が格納された JSON
│ ├── package.json # Angular プロジェクトで使うライブラリ情報が含まれた JSON
│ ├── proxy.conf.json # CORS エラーを回避する為の転送(proxcy)用 JSON
│ ├── src
│ │ ├── app # アプリケーション起点フォルダ
│ │ │ ├── app.component.html
│ │ │ ├── app.component.scss
│ │ │ ├── app.component.spec.ts
│ │ │ ├── app.component.ts
│ │ │ ├── app.config.ts # Angular アプリケーションの設定ファイル
│ │ │ ├── app.routes.ts # Angular アプリケーションのページ制御ファイル
│ │ │ ├── page-not-found # HTTP 404 エラー(該当リソース無し)用画面
│ │ │ │ ├── page-not-found.component.html
│ │ │ │ ├── page-not-found.component.scss
│ │ │ │ ├── page-not-found.component.spec.ts
│ │ │ │ └── page-not-found.component.ts
│ │ │ ├── shared # 共通ファイル
│ │ │ │ ├── models # データのインターフェースを定義するフォルダ
│ │ │ │ │ ├── index.ts # バレルファイル
│ │ │ │ │ ├── memo-ui.ts
│ │ │ │ │ └── memo.ts
│ │ │ │ └── service # API を管理するフォルダ
│ │ │ │ ├── api.service.spec.ts
│ │ │ │ └── api.service.ts
│ │ │ ├── todo # メモ編集画面
│ │ │ │ ├── todo.component.html
│ │ │ │ ├── todo.component.scss
│ │ │ │ ├── todo.component.spec.ts
│ │ │ │ ├── todo.component.ts
│ │ │ │ ├── todo.service.spec.ts
│ │ │ │ └── todo.service.ts
│ │ │ └── todo-list # メモ一覧画面
│ │ │ ├── todo-list.component.html
│ │ │ ├── todo-list.component.scss
│ │ │ ├── todo-list.component.spec.ts
│ │ │ ├── todo-list.component.ts
│ │ │ ├── todo-list.service.spec.ts
│ │ │ └── todo-list.service.ts
│ │ ├── assets # web サイトで使用するリソース(イメージファイル、JSON等)を配置するフォルダ
│ │ │ └── json # AP サーバーを使わないで API 制御する為のダミーデータ
│ │ │ ├── create.json
│ │ │ ├── delete.json
│ │ │ ├── memo-list.json
│ │ │ ├── memo.json
│ │ │ └── update.json
│ │ ├── favicon.ico # ファビコン(ブラウザのタブに表示されるサイト用のアイコン)
│ │ ├── index.html # Angular アプリケーションにアクセスされた時に最初に表示される html
│ │ ├── main.ts # Angular アプリケーションにアクセスされた時に最初に読み込まれる typescript ファイル
│ │ └── styles.scss # Angular アプリケーション共通のスタイルファイル(css / scss)
│ ├── tsconfig.app.json # typescrit 設定ファイル(アプリケーション用)
│ ├── tsconfig.json # typescrit 設定ファイル(共通)
│ └── tsconfig.spec.json # typescrit 設定ファイル(ユニットテスト用)
......
Angular単体でのアプリケーション開発
Angularを用いて、APサーバーやDBサーバーなしで動作を確認できるものを、画面・機能単位で実装しました。個々のプログラムを解説すると膨大になってしまうので割愛し、機能ごとにプルリクエストという形でまとめました。それぞれのプルリクエストに、実装において実施した作業(実行したコマンドなど)が記載されています。作業によって変更されたファイルおよび変更前との差分は「Files changed」タブを見てください。
- フロントエンドスケルトン作成
- 画面コンポーネントの作成、ルーター(画面遷移)の実装
- メモ帳一覧の実装
- メモ作成の実装
- mock api service 実装
- mock api 実装リファクタリング
- mock api 実装リファクタリング part.2
APサーバー・DBサーバー連携に関する実装
先ほど「CORSエラー対策」の章でエラー対策の設定をしましたが、これによって、フロントエンドとAPサーバー・DBサーバーを連携して動作確認することができます。連携するために追加・修正したプログラムを、こちらもプルリクエストの形でまとめました。
- フロントエンドとAPサーバーの接続
- APサーバーの更新
- CORSエラー解決のための修正
- PATCHエンドポイント修正
- フロントエンドの更新APIのURLにid(メモid)を追加、バックエンドのallowed_methodsにpatch, deleteの追加
フロントエンド開発の動作検証
今回のフロントエンド開発で実装したプログラムの動作検証を行います。
APサーバーの起動
さくらのVPS上のサーバーにログインし、下記のコマンドを実行してAPサーバーを起動します。
$ cd my_actix_app/
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.15s
Running `target/debug/my_actix_app`
プロキシ設定・サーバーアドレスの変更
proxy.conf.jsonの修正
プロキシ設定(転送)を有効するために、frontend/proxy.conf.jsonを以下のように修正します。(diffコマンドによる差分を示します。変更箇所はその下の画像をご覧ください)
$ diff --git a/frontend/proxy.conf.json b/frontend/proxy.conf.json
index 196f7a9..6b10632 100644
--- a/frontend/proxy.conf.json
+++ b/frontend/proxy.conf.json
@@ -1,6 +1,6 @@
{
"/api": {
- "target": "サーバーアドレス",
+ "target": "http://xxxxx.vs.sakura.ne.jp",
"secure": false,
"changeOrigin": true
}
(END)
api.service.tsの修正
APIが正しくリクエストを出せるようにするために、frontend/src/app/shared/service/api.service.tsを以下のように修正します。(diffコマンドによる差分を示します。変更箇所はその下の画像をご覧ください)
$ diff --git a/frontend/src/app/shared/service/api.service.ts b/frontend/src/app/shared/service/api.service.ts
index 10a2e54..c738aa0 100644
--- a/frontend/src/app/shared/service/api.service.ts
+++ b/frontend/src/app/shared/service/api.service.ts
@@ -9,7 +9,7 @@ import { Memo } from '../models';
export class ApiService {
http = inject(HttpClient);
- apiUrl = 'サーバーアドレス/api/memos';
+ apiUrl = 'http://xxxxx.vs.sakura.ne.jp/api/memos';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
(END)
Angularアプリケーションの起動
ローカルPCにてnpm startコマンドを実行すると、Angularアプリケーションが起動します。
$ cd frontend
$ npm start
> todo-app@0.0.0 start
> ng serve
Initial chunk files | Names | Raw size
styles.css | styles | 93.34 kB |
polyfills.js | polyfills | 83.63 kB |
main.js | main | 1.89 kB |
chunk-4WXVOEFY.js | - | 1.46 kB |
| Initial total | 180.32 kB
Lazy chunk files | Names | Raw size
chunk-QIBVAIEI.js | todo-list-component | 11.86 kB |
chunk-WQS3Y732.js | todo-component | 8.50 kB |
chunk-Y2FJ7FHO.js | - | 1.23 kB |
chunk-AEC2WSUB.js | page-not-found-component | 1.08 kB |
Application bundle generation complete. [1.250 seconds]
Watch mode enabled. Watching for file changes...
➜ Local: http://localhost:4200/
➜ press h + enter to show help
このアプリケーションは4200番ポートでWebサーバが動作するようになっています。ブラウザにて http://localhost:4200/ にアクセスすると、下図のようなメモ一覧画面が表示されます。
Angularアプリケーション画面の解説
ここからはAngularアプリケーションの各機能を検証していきます。「さくらのVPSを使ってシステム開発に必要な知識を学ぶ 〜第11回〜」 において、アプリ画面の概要解説を行いました。その概要に基づいて解説します。
メモ帳一覧画面
起動時
ブラウザにて http://localhost:4200/ にアクセスすると、メモ帳一覧画面が表示されます。
このとき、アプリケーションから一覧取得API(GET)にアクセスし、取得したメモ情報を画面にセットしています。APIのURLは http://サーバー名/api/memos です。(「サーバー名」のところは、さくらのVPSサーバー名もしくはIPアドレスに読み替えてください)
一方、バックエンドではデータベースに対して「SELECT * FROM MEMOS;」というSQLが発行されています。そこでサーバ上でMySQLに接続し、MySQLのコマンドラインで同じSQLを発行して、DBサーバーから取得されるデータとブラウザに表示されるデータを比較し、データが正しく取得されていることを確認します。
全選択ボタン
全選択ボタンを押して、表左側のチェックボックスがすべて選択状態になることを確認します。こちらは画面制御のみの確認になります。
選択解除ボタン
選択解除ボタンを押して、表左側のチェックボックスがすべて選択解除状態になることを確認します。こちらも画面制御のみの確認になります。
削除ボタン
表左側のチェックボックスに印を入れて削除ボタンを押すと確認ダイアログ(下図)が表示され、「OK」を押すとデータが削除されます。
アプリケーションの動作としては、「OK」をクリックした時に削除API(DELETE)を実行します。APIのURLは http://サーバー名/api/memos/id です(idはメモIDの番号です)。
その後、バックエンド側でデータベースに対して「SELECT * FROM MEMOS;」というSQLを発行し、データベース上でもメモが削除されていることを確認します。
なお、チェックボックスに印を入れずに削除ボタンを押したときは、エラーメッセージが表示されます。
新規作成ボタン
新規作成ボタンを押すと、メモ作成画面へ遷移します。こちらについては、後述の「メモ作成・編集画面」にて解説します。
編集ボタン
表左側のチェックボックスに印を入れて編集ボタンを押すと、印が入っているデータの編集画面に遷移します。こちらも後述の「メモ作成・編集画面」にて解説します。
なお、チェックボックスに印を入れずに編集ボタンを押したときは、エラーメッセージが表示されます。
メモ作成・編集画面
メモ作成・編集画面における動作を解説します。この画面に遷移してくるのは、メモの新規作成時と既存メモの編集時の2つあります。それぞれについて、画面を表示するときの初期処理と、保存ボタンを押したときの保存処理があります。
初期処理:新規作成時
新規作成時の初期処理としては以下を実施します。
- タイトル/メモ欄を空白にします。
- 保存ボタンを非活性状態にします。
初期処理:編集時
メモ一覧画面に表示されているメモからいずれか1つを選び(操作例ではNo.5を選んでいます)、「編集」ボタンを押すとメモの編集画面に遷移します。このときの初期処理を説明します。
まずアプリケーションからメモの個別取得API(GET)にアクセスします。APIのURLは http://サーバー名/api/memos/id です(idはメモIDの番号です。操作例では5になります)。メモのデータを取得したら、取得したメモ情報を画面にセットします。さらに保存ボタンを活性状態にします。
一方、バックエンドではデータベースに対して「SELECT * FROM MEMOS where id = 5;」というSQLが発行されています。こちらもサーバ上のMySQLコマンドラインにて同じSQLを発行し、DBサーバーから取得されるデータとブラウザに表示されるデータが一致することを確認します。
保存処理:新規作成時
保存ボタンを押すと、まず確認ダイアログが表示されます。ここで「OK」を押すと保存処理が行われます。「キャンセル」をクリックした時はメモ作成画面に戻ります。
内部の動作としては、「OK」をクリックした時に新規作成API(POST)を実行します。URLは http://サーバー名/api/memos です。新規作成が成功するとメモ一覧画面へ遷移します。
一方、バックエンド側での確認としては、データベースに対して「SELECT * FROM MEMOS;」というSQLを発行し、新しく作成されたメモがデータベース上に記録されていることを確認します。
保存処理:編集時
編集時の保存処理も画面上の動きは同じで、保存ボタンを押すと確認ダイアログが表示されます。ここで「OK」を押すと保存処理が行われます。「キャンセル」をクリックした時はメモ作成画面に戻ります。
内部の動作は新規作成時とは異なります。こちらは「OK」をクリックした時に更新API(PATCH)を実行します。URLは http://サーバー名/api/memos/id です。更新が成功するとメモ一覧画面へ遷移します。
その後、バックエンド側での確認として、データベースに対して「SELECT * FROM MEMOS;」というSQLを発行し、新しく作成されたメモがデータベース上に記録されていることを確認します。
うまくいかないとき
画面にデータが表示されない場合や、データの登録・更新・削除ができない場合は、以下の事項を確認してみてください。
- APサーバーが起動しているか
- APIのURLが正しいか
- プロキシ設定が正しいか
デバッグの手順
エラーが出るなど期待通りに動作しないときはデバッグすることになります。ここではデバッグの手順を紹介します。なお今回はブラウザとしてChromeを使う例を解説します。
ChromeのDevToolsを表示
ChromeにはDevToolsという開発支援ツールが組み込まれています。まずはこれを表示します。表示方法を以下に示します。
- Chromeを起動します。
- アドレスバーに http://localhost:4200/ を入力しEnterを押します。
- ページが表示されたら、以下を入力してDevToolsを起動します。
- macOSの場合: Command+Option+i
- Windowsの場合: F12
なおDevToolsについては、さくらのナレッジに以下の記事があるので参考にしてください。
コードの表示とデバッグ
メモ一覧画面をデバッグする想定で手順を解説します。
devtools
のソースタブをクリックします。devtools
のソースタブ左側を下記の順でクリックします。- top →
http://localhost:4200/
→ src → app → todo-list → todo-list.component.ts
- top →
- この後、任意の止めたい箇所をクリックして、ブレークポイントを設定します。
- リロードや任意の操作をして、上記ブレークポイントに処理が到達したら、順々に処理を追います。
まとめ
今回は主にフロントエンド部分の実装に関して、以下の内容を解説しました。
- フロントエンド開発の考え方
- CORSエラーと対策
- ローカルでのフロントエンド開発の環境構築
- Angularの紹介
- フロントエンドの実装
- フロントエンド実装の動作検証
- デバッグについて
次回は、CI/CDについて解説したいと思います。