【Express】Node.jsを学んでみる 最初の一歩
概要
割とReactを勉強してるとデータを追加したり保存したりするのにmongo.dbなどと連携することがあるんだなと思った。
そこでNode.jsも勉強しておこうと思い、今回は主流となっているExpressを使って簡単な流れを
学んでみる。
最終目的
今回の最終目標は以下とする。
- Expressを使ったサーバー立ち上げの流れ
- ルーティングの設定
- ミドルウェアへの簡単な理解
実際の流れ
では、実際に作業をやっていく。
適当なフォルダを作ってVSCodeで作業する。
Expressとnodemonをインストール
Node.jsはサーバーサイドJavascriptの実行環境。
だた、Node.jsではExpressというフレームワークを使われることが多く、生のNode.jsを書くことがほとんどないだろうという事でExpressをインストールする。
nodemonとは、作業していると変更することが多々ありますが、その都度変更を有効するためにサーバーを起動するのがめんどくさいのですが、こちらのnodemonを使うと自動的に再起動して変更を有効としてくれる。
ではまずターミナルを立ち上げ、まずはpackage.jsonを作成する
npm init -y
その後、Expressとnodemonをインストールするのでターミナルに以下のコマンドを打つ。
npm i express nodemon
すると、package.json に以下の設定が追加されます。
"dependencies":
"express": "^4.18.1",
"nodemon": "^2.0.16"
}
また、サーバーを起動させるコマンドでnodemonを使用するようにpackage.jsonに以下の設定をしておく。
server.js
は実際の作業ファイルになるので、名前が違う場合は変更。
"scripts": {
"dev":"nodemon server.js"
},
Expressでサーバーと立ち上げてみる
server.js
というファイルを作成して実際にExpressを読み込んで作業してみる。
//expressのモジュールを読み込む
const express=require("express");
//expressをインスタンス化する
const app=express();
//ポート番号を設定する 例:3000
const PORT=3000
//listenイベントで3000番ポートでサーバーを起動する。
//consoleで確認
app.listen(PORT,()=>{
console.log("start server")
})
サーバー起動までの流れ
実際の流れは以下のようになる。
- expressのモジュールを読み込む
- expressをインスタス化する
- ポート番号を決める
- listenイベントでサーバーを起動
Expressを使う場合はもはやテンプレートのような流れ。
ポート番号を変数に入れてるが別に入れなくてもいい。
ルーティングの設定
次はルーティング(URL)の設定。
expressをインスタンス化したappオブジェクトのgetメソッドの第1引数にルーティングのURLを設定できる。以下ユーザー(user)のページと想定したルーティング。
app.get("/user",(req,res)=>{
res.send("ユーザー");
})
/user
とすることで、'localhost:3000/user'にアクセスすることができる。
またgetメソッドの第2引数にコールバック関数を指定しているが、引数にリクエスト(req)とレスポンス(res)オブジェクトがある。
上記はres.send()
でユーザーという文字列を返しているので、URLにアクセスするとユーザーという文字列が表示される。
ルーティングファイルの分割
ルーティングの設定で、ユーザー(/user)の例を挙げたが、さらにユーザーの詳細(/user/info)のルーティングの設定をしたり、商品ページのルーティング(/product)や詳細ページ(/product/info)といったルーティングを増やしていくと乱雑となってくる。その場合、ファイルを分割すると便利。
仮にユーザーとユーザーの詳細を分割する例。
user.js
というファイルを作り、以下の設定にする。
//expressのモジュールを読み込む
const express=require("express")
//expressのRouterインスタンスを作成
const router=express.Router()
//Routerインスタンスからgetメソッドで呼び出す
router.get("/",(req,res)=>{
res.send("ユーザー");
})
router.get("/info",(req,res)=>{
res.send("ユーザー情報");
})
//モジュール化して、外部で利用できるようにする
module.exports=router;
express.Router
クラスを使用します。Router
インスタスからgetメソッドを呼び出す。ただし、ルーティングは以下となる。
- ユーザートップ(/)
- ユーザーの詳細(/info)
なぜこうなるのかというとuser.js
を元となるserver.js
で読み込む際に設定するから。(後述)
その後、module.exports
でモジュール化する。
分割したルーティングファイルを読み込む
ユーザー関連のルーティングをuser.js
に記述したら、server.js
で読み込んで以下の設定で使用する。
//requireでuser.jsを読み込む
const userRouter=require("./user")
//useメソッドでユーザー関連のルーティングを設定
app.use("/user",userRouter)
読み込んだルーティングを設定するにはexpressのuseメソッドを使用する。
useメソッドはミドルウェア関数とよばれる。
ミドルウェア関数のルーティングは、app.use(path,handler)
のように、app.use
の第一引数にpath
を与えることで実現できる。
今回は、そのpath
にユーザーの「/user」を設定し、第2引数のhandler
に読み込んだuserRouter
を指定することで、ルーティングを実現している。
ミドルウェアについて
ミドルウェアという言葉が出てきたので、簡単にメモ。
サーバーに対してリクエストを送る前に何かしらの処理・・・例えば、認証が終わってるのかどうかなど、途中で処理を差し込むことをミドルウェアという。
このミドルウェアは、リクエストとレスポンスのオブジェクトを受け取り、それになんかしらの処理を行うのがuse関数である。
単純にログを出力するミドルウェアの例。
//ミドルウェアLoggerを実行する
router.use(Logger)
//ミドルウェアの処理
function Logger(req,res,next){
console.log("ミドルウェア実行")
next();
}
注意点として、ミドルウェアを使用する場合はuseメソッドはファイルの上に記述する。ページの下に記述して途中でrenderメソッドなどあるとそこでページの処理が止まってしまいミドルウェアが実行されない。
//実行されない //////////////////////////////////
app.get("/",myLogger,(req,res)=>{
res.render("index",{text:"expresss ejs test"});
})
router.use(Logger)
//実行される //////////////////////////////////
router.use(Logger)
app.get("/",myLogger,(req,res)=>{
res.render("index",{text:"expresss ejs test"});
})
特定のルーティング対してミドルウェアを実行
アプリケーション全体にミドルウェアを実行するのではなく、特定のルートに対して、ミドルウェアを実行したい場合も多いと思う。
以下のようにgetメソッドの第2に引数に処理したい処理を指定するとミドルウェアとして実行される。
以下ユーザー(/user)に対してのミドルウェア
app.get("/user",Logger,(req,res)=>{
res.send("ユーザー")
})
//ミドルウェアの処理
function Logger(req,res,next){
console.log("ミドルウェア実行")
next();
}
まとめ
とりあえず今回はExpressってどんなの?
という事で、実際にサーバーを起動して文字を表示させるところまでやってみた。
参考サイト
Discussion