Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9042

Angular + Expressの開発環境サンプル

$
0
0

はじめに

Angular + Expressの開発環境サンプルを作ったので公開。

Angular + Express Example

DBはPostgreSQLを使用しています。
最低限の構成で、簡単なCRUD機能を実現しています。
デモ用などに簡単なWEBアプリを作りたい時とかに、ベースにできればと。

動作環境

動作確認したときの環境は、以下の通り。

・node.js 12.16.1
・npm 6.13.4
・PostgreSql 12.1

機能

サンプル機能として、入退室時間とユーザを登録・表示する画面を作成しています。

ログイン画面

Angular+Express Example01.png

入退室管理画面

Angular+Express Example02.png

ユーザ管理画面

Angular+Express Example03.png

登録ダイアログ画面

Angular+Express Example04.png

プロジェクト構成

フロントエンドとバックエンドをひとまとめにしたようなプロジェクト構成にしています。

・ルートフォルダ ─┬─ front(angular)
          └─ server(express)

という構成です。
起動するのはサーバ側のnodeだけで、画面表示のリクエストもサーバ側(express)で受け付けて転送しています。

angular側も普通にng serveして別サーバにすることも可能ですが、小規模なものであればフロントエンドとバックエンドを一人で実装することも多いでしょうし、このほうが軽そうなので。

実行

実行方法は、git の ReadMe に記載の通りです。
PostgreSQLのデータベースを準備し、テーブル・初期ユーザを登録した後、ルートフォルダからnpmコマンド(npm installnpm run watchなど)を叩くだけです。

事前にインストールなどが必要なのは、
・PostgreSQL
・node(npm)
くらいのはずです。
(必要があればgitも。)

開発時の起動

ルートにてnpm run watchを実行すると、ソースの変更を監視して起動してくれます。
ブラウザにて、http://localhost:3000/にアクセスするとログイン画面が表示されるはずですので、

・ユーザID:1
・パスワード:123456

でログインしてください。

front/serverともに、ソースを修正・保存すると、自動的にビルドが走ります。
ブラウザは自動更新されませんので、必要に応じて手動でブラウザ更新してください。

デバッグ

サーバ側でデバッグしたいときは、VSCodeなら「Attach Node」でnodeのプロセスを選択するとブレークポイントを使用してデバッグが可能になります。
debug-01.png

クライアント側は・・・何も用意してないので、ブラウザのデバッグ機能を使ってください。
debug-02.png

実装についての補足

以下、細かい機能とその実装について補足します。

画面デザイン

画面デザインについては、プロジェクトによってそれぞれ見直しすることになると思いますので、かなり適当です。
いちおう、「Bootstrap」と「Angular Material」を使用してある程度は調整していますが、必要に応じて見直ししてもらえればと。

ルーティング

「server/src/app.ts」にて、リクエストのルーティングをしています。

app.ts
// Expressのルーティング(認証不要のもの)app.use('/api/',indexRouter);app.use('/api/common/auth',authRouter);// トークンの正常チェックapp.use('/api/*',async(req:any,res:any,next:any)=>{consttoken=req.headers['access-token'];if(!token){res.status(401);returnres.json({message:'No token provided'});}try{constdecoded=awaitjwt.verify(token,tokenConf.accessTokenSecretKey);req.decoded=decoded;next();}catch(e){res.status(401);returnres.json({message:e.message});}});// Expressのルーティング(認証が必要なもの)app.use('/api/common/db',dbRouter);// Angularのルーティングapp.use(express.static(path.join(__dirname,'../../front/dist')));app.use('/*',express.static(path.join(__dirname,'../../front/dist/index.html')));

まずはAPI側(URIが/api/・・・のもの)の処理として、認証されていなくても実行できるAPI(ログイン用のAPIなど)を受け付けます。
その次に認証チェックを行い、エラーの場合は401を返して終了します。
認証チェックOKの場合、その次で認証前提のAPIの処理をしています。

その次で、Angular側へのルーティングをしています。

ログイン

JWT形式のトークンで管理しています。
いちおう、アクセストークンとリフレッシュトークンを使用するようにはしていますが、管理方法はいまいちです。
・リフレッシュトークンをアクセストークンと同じようにLocalStrageで保存している。
・トークンをDBなどに管理しておらず、ログアウト時に破棄などもしていない。
・暗号化も適当。
実際に使えるようにするには、上記あたりも見直しが必要だと思います。
とりあえずはトークン生成、受け渡しのサンプルとして。

トークンのリフレッシュ

front/src/app/common/services/http.ts
で、アクセストークンの期限が切れていたら、リフレッシュトークンによる更新を試みるようにしています。
リフレッシュトークンの期限はデフォルトで180日にしてるので、一度ログインすると180日間ログイン状態を維持する動きになります。

interceptでやるのが一般的?かもしれませんが、どうにもキレイに実装できない(Callback地獄になってしまう・・・)ので、諦めて原始的な手法(HttpClient をラップする関数、callAPI を作成)で実装しました。

サーバ側のデータアクセス

「api/common/db」にて、とりあえずserver/src/config/sqlに定義したSQLを実行して返却する、というだけの共通的なAPIを用意しています。
実際には、それぞれ個別の処理を行うAPIを追加していくことになると思いますが、データアクセスのサンプルということで。

ダイアログ表示

client/src/app/view/common/dialogs/simpleDialog.componentにて、簡単なダイアログを共通的に表示できるようにしています。
これも、実際には個別にダイアログを増やしていくことになるかと思いますが、ダイアログ表示のサンプルとして。

列挙型、的な定義について

「1:男性, 2:女性」みたいな定義を汎用的に使用したいので、
「client/src/app/common/defines/enums.ts」
でまとめて定義しています。
表示変換用のpipeとかも同ファイルに定義していて、ちょっとゴチャっとしていますが・・・まあ、細かいファイル構成はご自由にして頂ければということで。

多言語化

ngx-translateを使用して多言語化対応しています。
よく考えたら、いうほど多言語化対応が必要になることもないので、サンプルとしては不要だったかも。
英文は、google先生まかせなので、怪しいです。

DBについて

DBはPostgreSQLを使用していますが、RDBであれば他のものに簡単に置き換えできると思います。(試してませんが。)
「server/src/utility/postgres.ts」
で一般的なコマンドをラップしてますので、そのあたりを書き換えればいけるかと。

その他、課題・雑感など。

・せっかくTypescriptにしてるのに、型定義をサボっているところが多いです・・・。
 特にサーバ側は、とりあえず Typescript にしたってだけの状態です。
 今だと、Nest.js みたいなフレームワークを導入したほうが幸せになれるかも?
・最低限のシンプルな構成にしたかったので、一般的なアプリケーション構成(サービス層とかコントローラ層とか)もバッサリ省略しています。
 必要に応じて分離して頂ければ。
・日付と時刻が同時に選択できるカレンダーが欲しくて、flatpickr を使ってみましたが・・・時刻入力の挙動がいまいちなような・・・。
 これなら、Angular Material の Picker を使ったほうがよかったかも。
・スマホでもそれなりに表示できるようにしましたが、グリッド表示などはいまいち・・・。
・Callbackな書き方が好きじゃないので、なるべくAsync-Awaitを使うようにしてます。
・Angular9が出たので、アップデートしてみました。
 レンダリングエンジンが変わったらしいですが、いまいちわかってません。
 ビルド時のメッセージがなんか変わったかなーくらいしか。。。
 それより、Typescript3.7対応になったので、Null条件演算子(hoge?.name みたいな書き方)が使えるようになったのが嬉しい。。。
・Heroku での実行手順を以下に投稿しました。
 Angular + Express + PostgreSQLのWEBアプリをHerokuで実行する手順


Viewing all articles
Browse latest Browse all 9042