Express Sequelize React TypeScriptでアプリケーション開発

React Redux Express Sequelizeで作る写真管理アプリケーションのサンプル

どうも、ぽっぽです。

今まで調査してきた情報をもとにアプリケーションを開発してみました。

簡素な写真アプリケーションです。たんにTodoアプリに写真を登録できるようにしてみました。1から構築した手順とソースを紹介します。

写真の扱いはWEBアプリケーションでは要件になることが多いです。シンプルな方法としては画像ファイルをWEBサーバーで配信します。今回はデータベースから取り出してbase64でエンコードした文字列に変換し、フロントエンドでその文字列を画像として表示させる方法をとりました。HTML5の機能にあるので分かってさえいれば簡単です。

WEBサーバに画像として配信する方法だと、データベースから取り出したファイルを使わなくなったら消したり、使わないという要件をどのように定義するか考えたりやることが増えるので避けました。

ReactでTypeScriptが使えるように環境を構築

npx create-react-app photo-apli --template typescript
npm i redux react-redux @types/react-redux @reduxjs/toolkit redux-thunk
npm i --save-dev redux-devtools
npm i office-ui-fabric-react

ReactでTypeScriptが使えるように環境を構築し、ReduxとUI Fabricをインストールします。

コンポーネントの設計

コンポーネントはTodoアプリと同じ構成にします。あまり複雑なことを一度に取り入れると問題が起こったときに切り分けるのが一苦労だと思いました。

  • PhotoHeader
  • PhotoList
  • PhotoListItem
  • PhotoFooter

今回は写真を登録・表示するため、PhotoHeaderPhotoListItemに手を加えています。

Todoアプリではidはuuidを使ってフロントエンドで採番していました。今回はデータベースで採番して取得し、Stateを更新することにしました。採番はデータベースにまかせます。

UI Fabricにはファイルアップロードのためのコンポーネントは見つかりませんでした。そこで通常の<input type=file>を用意して別のコンポーネントから操作するようにしています。

Expressのインストールとその他のライブラリ

npx express-generator --view=pug server
npm i
npm i multer
npm i --save-dev cors nodemon npm-run-all

expressをインストールするときにviewを指定しないとテンプレートエンジンがjadeになります。jadeは非推奨のテンプレートエンジンで現在はpugとなっています。そこで明示的にpugを指定します。詳細は公式ドキュメントを参照してください。

フロントエンドはReactを使うのでviewは必要ないのですが、開発時にエラーが起こるとエラーページを表示するようにexpress-generatorが段取りしてくれているのでviewをそのまま利用しています。

multerはファイルアップロードのためのミドルウエアです。

セキュリティ上の理由で、ブラウザはスクリプトによって開始されるオリジン間のHTTPリクエストを制限しています。(参照
corsによってその制限を許容するようにしています。
フロントエンドはlocalhost:3000、バックエンドはlocalhost:4000でローカルの開発環境で動作させています。このようにドメインが異なっても、corsがあるとフロントエンドとバックエンドでajaxによる通信が出来るようになります。

nodemonは指定したディレクトリ配下のファイルの更新状態を監視して変更があるとデプロイしてくれます。Express側のソースの更新があると自動でデプロイされるので、いちいちnpm startをせずに済みます。

npm-run-allはフロントエンド側とバックエンド側で別々で同時に起動させるためインストールしています。package.jsonのscriptsでrun-pというコマンドで同時起動しています。

  "scripts": {
    "start:client": "react-scripts start",
    "start:express": "nodemon -w server bin/www",
    "start": "run-p start:express start:client",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

Sequelizeのインストール

npm install --save sequelize
npm install --save pg pg-hstore
npx sequelize-cli init
npx sequelize-cli model:generate --name Photos --attributes title:string,photo:blob,kind:string,complete:boolean
npx sequelize-cli db:migrate

Sequelizeのインストールとモデルを定義します。

pgとpg-hstoreはデータベースにPostgresを使う場合です。他のデータベースを使う場合は公式ドキュメントを参考に必要なアプリケーションを指定してください。

Photosテーブルにphotoというカラムを定義したのは作っていて後から後悔してしまいました。フロントエンドとバックエンドでオブジェクト定義を揃えたのですが、たまに混乱してしまいます。名前はちゃんとつけないとだめですね。

photoはバイナリデータを格納するカラムなのでblob型にしています。

サンプルアプリケーションのソース

サンプルアプリケーションをこちらからダウンロード出来ます。

npm install
npm start

Todoアプリを動作させる場合、NodeJSのコマンドプロンプトを開いて、ソースをダウンロードして展開した場所(package.jsonファイルがある)に移動します。1行目のコマンドを実行します。package.jsonのパッケージをインストールして、インストールが終わるまで数十秒ほど待ちます。
2行目のコマンドを実行するとブラウザにTodoアプリが表示されます。

終わるときは、コマンドプロンプト上でCtrl + Cをタイプします。

npx sequelize-cli initで生成される「config/config.json」ファイルは含まれていません。各自の環境に合わせて編集する必要があります。

所感

他の方のソースを読んで動かして理解した気になっていました。実際1から作ってみると手が動かないものですね。また最初から作るとなっても何も見ずに書くのは難しいかもしれません。

フレームワークはホントは実装しないとならない機能を事前に実装してくれているので使わない手はないと思います。でもフレームワークのルールを覚える必要があり新規プロジェクトでいきなり使うと思った以上に調査時間を必要とします。

TypeScriptを使ってReactを使ってみようと思ったことから始まったのですが、Ajaxを使ってRest通信しようとするとRedux、Thunkなどのフレームワークも必要だったことが分かりました。使わなくてもよいのですが自ら実装するより使ったほうが安全・安心だと思いました。

フロントエンドとバックエンドはたいてい異なる言語となります。一人ですべて開発する場合シンタックスの違いで混乱することもあります。納期が近く急ぐとなおさらです。

そこでバックエンドはNodeJs環境で利用出来るExpress、Sequelizeを使いました。JavaScriptで記述できるからです。フロントエンドで調べたやり方がそのままバックエンドでも使えることは体験してみるとありがたいなと思えました。

フレームワークは使い方が分かってしまえばプログラミングのコード量が減ります。フレームワークを利用する初期段階は、その方法を調べるところに時間を使います。

エンジニアとしてはこの調査作業でまず答えにたどり着くかが最も大事だと思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

先頭に戻る