調査：著名サイトのパスワードリセット用 URL

# きっかけ

パスワードリセットのように、アクションそのものっていう URL 設計をどうしたものかと悩み、著名サイトを調べてみたのでメモ。正直、悩む問題というよりは決めの問題だと思うのだけど、心理的にしっくりこないといつまでもモヤモヤしてしまうので、なんとかしたい。

URL は API に限らず、静的ページでもアプリケーションでも、リソースを表すようにしたい、というのが発端。なぜリソースにしたいかというと、そうじゃないと気持ち悪いから。気持ちの問題です。

# お断り

ここで調べた各サイトが RESTful な URL を指向（または、設計）しているかどうかはわかりません。また、調べた内容は極めて限定的な内容であり、これをもって、各サイトの URL 設計の全体的な方針がわかるわけでもありません。

記事中には、あたかもサイト全体の URL 設計に言及しているかのように受け取れる箇所があるかもしれませんが、そうではなく、あくまでも、パスワードリセットに関する URL についての記述です。

また、特定のサイトおよびその URL 設計を非難する意図をもって書いているわけでもありません。そして、あなたの著名サイトと私の著名サイトが異なっている可能性はかなり高いでしょう。あしからず。

その上で、明らかに誤解している箇所がもしあるようなら、ご指摘ください。

# 調査結果

## URL に動詞を採用しているサイト

調べた中では多数派を占める。

Google は旧パスワードの入力があったり、確認用メールアドレスの選択があったりと、その充実度と親切度（お節介度）において他の追随を許さない。ただ、URL の命名規則は統一されている風でもなく、つぎはぎ感がある。過渡的な状況なのか。

Facebook はまずアカウントの検索から始まるので、やや毛色が異なる。`ctx=recover` というパラメーターからは、かなりシステマティックな匂いを感じる。`lwv=110` については意味がよくわからず。

その他、単独の `reset` についてはリソースと呼ぶのはやや無理があるかと思い、動詞とみなした。

```:Google
/VerifyOldPassword?cpr=...
/accounts/recovery/recoveryoptions
/accounts/recovery/dispatchrecovery
```

```:Facebook
/login/identify?ctx=recover&lwv=110
```

```:Twitter
/account/begin_password_reset
/account/send_password_reset
```

```:Instagram
/accounts/password/reset/
```

```:Pinterest
/password/reset/
```

```:Azure
/ResetPassword.aspx?wreply=...
```

```:niconico
/password/reset
```

```:Backlog
/PasswordReminderDisplay.action
```

```:Chatwork
/service/passremind.php?type=...
```

## URL で状態を表していると思われるサイト

リソースとして「パスワードを忘れた状態」を表しているように見受けられるもの。

DigitalOcean はなかなか興味深い。`new` は手続きの初期状態を表しているのか。Bluemix の `forgot_password_start.html` についても同様のロジックが働いているように思える。ただ、もしこれをレビューで見かけたら何か言わずにはいられない気がする。

`forgot_password` 状態を POST するとメールが送信される、というのは直感的か否か。微妙なところだ。

```:Qiita
/sessions/forgot_password
```

```:Slack
/forgot?email=...
```

```:DigitalOcean
/forgot_password/new
```

```:AWS
/ap/forgotpassword?...
```

```:Bluemix
/account/us-en/forgot/forgot_password_start.html
```

## URL に名詞を採用しているサイト

はてなの `reminder` は範囲が広すぎると思う。予定なのか、パスワードなのか、記念日なのか。Snapchat はこれまでの中で一番しっくりくるが、やや長い。あと、個人的な趣味でアンダースコアはやめたい。

Yahoo はまずアカウントの検索から始まるのでちょっと毛色が違うけど、名詞の選択は明快で的確。機能的には Facebook と同じなのに、URL の印象は鮮やか。

```:はてな
/reminder
```

```:StackOverflow
/users/account-recovery
```

```:Github
/password_reset
```

```:Snapchat
/accounts/password_reset_request
```

```:Yahoo
/account/challenge/username?done=...
```

# 考察

パスワードリセットを単一のアクションと見なさずに、「パスワードリセット申請届」というリソースがあって、それを GET なり POST することで機能が具現化すると考えてみる。要するに、モノをやり取りすることで、コトを実現する。しかしそれと引き換えに動詞は制約を受け、微妙なニュアンスは失われる。単純な CRUD に置き換えられてしまう。

そこでつい、ショートカットしてそのものずばりのコトに飛びつきたくなる。その結果、動詞的な URL が生まれるのではないか。動詞的な URL の背後には、正確さを失いたくないという想いが、意識的にしろ無意識にしろ、表れていると思う。

ショートカットを我慢して、限定された動詞の世界（GET/POST/PUT/PATCH/DELETE など）でせせこましく実装するのが良いのか、表現力の豊かなコトの世界（ResetPassword など）で伸び伸びと実装するのが良いのかは結局のところ好みの問題で、個人的には窮屈でも、統一された「URL=リソース」の世界に生きたいと思う。こうして不寛容が生まれ、チームの和が乱れる。

パスワードリセットは陳腐な例で、仔細に検討する価値はないけれど、「～～届」という概念は、適用範囲の広いパターンのような気がする。

```:パスワードリセット
/accounts/password-reset-request
```

ただ、そもそもログインできていないので、`accounts` の階層に含める必要はないのかもしれない。

```:パスワードリセット
/password-reset-request
```

あるいは、ユーザーからの要求・請願というリソース群があるとするなら、その配下のリソースとして表現できるかもしれない。

```:パスワードリセット
/requests/password-reset
```

ただそうすると、`GET /requests` されたときに何を返すかという問題も出てくる。管理者アカウントなら、全ての要求・請願を閲覧できていいかもしれない。

結局、狭い世界でも複雑さは十分に複雑なままだ。あるいは、狭い世界に拘泥するからこそ解消されない複雑さというものがあるのかもしれない。

# まとめ

著名なサイトのパスワードリセット用 URL を調査してみた。その結果、URL に名詞を採用しているサイトは、それほど多くないことがわかった。また、Yahoo のように URL 設計に哲学を感じさせるサイトがある一方で、割と雑なというか、あまり気を使っていないのかな、と感じさせるサイトもあった。気を使う人は少数派なのかもしれないし、正直、余計なお世話もいいところだ。

モヤモヤは少しおさまったが、依然として URL は難しい。