パスパラメータ"/:id(\\d)"はどういう意味？　Node.js Expressのパスパラメータの設定の色々

## はじめに
Node.jsのExpressでは、以下のようにパスパラメータに正規表現を使う事ができる。

```js
app.get('/posts/:id(\\d+)', (req, res) => {
    console.log(req.params.id);
    res.end();
});
```

今回は、Expressのパスパラメータの書き方の設定方法について、その種類とその挙動（curlコマンドでAPIを呼び出した時のconsole.log(req.params.id)の出力内容）について実際に試してみて理解を深めてみたのでそれについてみていく。

※Expressのversionは4.17.1になります。

## Expressのパスパラメータの設定方法の種類
以下のように設定方法は何種類かあり、それらについてどのようなconsole.log(req.params.id)の結果が得られるか？を見ていく（他にも設定方法があるかもしれないが今回は以下の5種についてみていく事にする）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/a4dc65b6-228e-4e00-007d-1f4927861a05.png)

・参考：[Route parameters](https://expressjs.com/en/guide/routing.html#route-parameters)
・参考：[Expressでrouterで正規表現を用いてURLを指定し、そのパラメータを取得する](https://dev.classmethod.jp/articles/express_router_param_get/)

### 基本形の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/fbdcfcd3-76ba-2d8e-59f7-4096ab2d042f.png)

### オプションの結果
オプションとは、パスとしてあってもなくてもよいという設定の仕方になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/d7f4745a-f90a-47a4-4482-c1e25a9e7edc.png)

### 0以上
ここでいう0以上とは、正規表現の"\*"の事であり、直前の文字0回以上繰り返しという意味。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/2988c7eb-a601-1ed4-0d56-1517d7f0f008.png)

※Express4.x系では、正規表現中の"\*"が通常の方法で解釈されないという注意書きがあるので、推奨とされている"{0,}"を使う方がいいだろう。今回はあくまでパスパラメータの書き方の設定方法の違いを見ていくのが趣旨なので正規表現の0回以上を意味する"*"でパターンを見ている。

> In Express 4.x, the * character in regular expressions is not interpreted in the usual way. As a workaround, use {0,} instead of *. This will likely be fixed in Express 5.

### 1以上
ここでいう1以上とは、正規表現の"+"の事であり、直前の文字1回以上繰り返しという意味。

以下の図を見てわかるようにパラメータの取得がおかしくなってしまう…。そこで次に見ていくカスタムを使ったパスパラメータの設定で意図したパラメータの値を取得できるようにしてあげる必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/7b1c28e9-3e53-346e-5331-ce97ffb92005.png)

### カスタム
正規表現"\d+"とは、数字の事を意味するので、以下の図の通り数字のみがパラメータとして取得されるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/73944e17-ffa5-93b9-95b5-5376fc7289ce.png)

※\はエスケープが必要なので、\\のように実装では2つ繰り返す必要があるので注意（公式にも書かれている）。

> Because the regular expression is usually part of a literal string, be sure to escape any \ characters with an additional backslash, for example \\\d+.

## まとめとして
今回はNode.jsのExpressのパスパラメータの設定方法のパターンを見ていく事で、正規表現が使える事も理解できた。この正規表現を使えば、例えばパスパラメータで数字のみを受け取りたいといったときに、関数内で判定を行う必要がなくなり実装が楽になるだろう。ただ実際の実装としては、HTTPリクエストのvalidation実装に関わる話なので、[express-validator](https://github.com/express-validator/express-validator)を使った実装などがいいと思われる。express-validatorを使ったvalidationの実装については[REST APIをExpressで実装する際にrequestのスキーマvalidation・sanitizationをするには？](https://note.com/shift_tech/n/n1ab6813fdcbc)や[ExpressでREST APIを実装する時にreq/resのvalidationを楽に実装できるライブラリを使ってみた](https://note.com/shift_tech/n/n66f43685f2f9)を参照。

## おまけ
### パスパラメータの名前なしで正規表現のみを使うとどうなるか？
上記では、パスパラメータの設定だったので":id"の後にオプションを付けていたが、仮に":id"をなくして（名前なしにして）実装するとどうなるのか？を見てみると、以下の図のような結果になる。

```js
app.get('/user/(\\d+)', (req, res) => {});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/9cfa15df-9799-280c-ca4f-85c0ea3d87d8.png)
これは、パラメータとして使わないが、URLのパスマッチで数字があるものにマッチさせたい時などに使ったりする。