プログラミングの勉強をするときは、非機能要件についても勉強しましょうね（はあと）

こんにちは。
ふくしまです。(@MasuraoProg)

華の１９８６年（※１）生まれの３３歳、麗しき男です。

さて、エンジニアになるための勉強を初めて１年が経ちました。
この１２月で、WEBエンジニア（見習い）になれたので、頑張ってよかったです。

さて、早速ですがコードを書く練習をしていた時代に知らなかった言葉と最近出会いました。

*「非機能要件」*です。

以下、初学者向けの記事となりますので、つよつよエンジニアの方は踵を返してお帰りください。

---

#本稿の対象者
・エンジニアになりたくて勉強している人（非エンジニアな人）
・個人の趣味でプロダクトしている人（業務としてのプロダクトをしたことがない人）

---

#非機能要件との出会い。

現在、研修としてシコシコと与えられた課題に対するプロダクトを行っています。
ちょっとは勉強しているので、苦しみながらもまあなんとか作り上げるわけです。
ちなみに、今扱っている言語はみんなが大好きなPHP（※２）です。

さて、その日は課題がTODOリストの作成だったので、仕様に沿って作成し、
上長にmerge request（※３）しました。

すると、一言。
「非機能要件的な部分も確認しておいて〜」

全く知らない言葉に戸惑いました。
そこで、google先生に尋ねました。

---

#非機能要件とは。

字のごとく「機能に非ず。」な要件です。

---

###そもそも機能要件とはなんぞや？
機能要件とは、機能の要件。
つまり顧客がシステムに求める機能のことです。

例えば、今回私が課題で作ったのはTODO　WEBアプリですが、
この場合は、
・TODOの記録ができる。
・内容の編集ができる。
・TODOの削除ができるといった内容です。
いわゆるCRUD（※4）というやつです。

---

##では非機能要件とはなんぞや？

機能要件とは対になる概念です。
つまり、顧客が機能面以外にシステムに求める要件になります。
もしくは、機能以外の顧客が認識できていない部分の機能かもしれません。

---

##具体的な非機能要件。「非機能要件6大項目」

この非機能要件については、[IPA](https://www.ipa.go.jp/sec/softwareengineering/std/ent03-b.html)に
非機能要件6大項目として記載があります。
以下の通り。

---

<img width="580" alt="スクリーンショット 2019-12-25 22.20.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/49d2399b-7937-668b-8f4c-5553412a3191.png">
*非機能要求グレード本体（日本語版）より抜粋*

---

項目をまとめると以下の６件。

- 可用性
- 性能・拡張性
- 運用・保守性
- 移行性
- セキュリティ
- システム環境・エコロジー

---

見ての通り、インフラ的な部分や、エコロジーなど個人ではなんにもできない部分が目立つ。
ただし、個人プロダクトでもできる部分としては、**セキュリティー**などがすぐにとっつきやすいでしょう。

---

さすがに、情報セキュリティ教育は今回の記事では対象外です。
ただ自分のプロダクトを意地悪に利用してセキュリティー問題を起こす輩がいるかも知れません。
ということで、初学者は自分のプロダクトに対して、
機能という観点だけでなく非機能要件としてのセキュリティーの部分を確認してみましょう。

---

##プロダクトの例
例えば、個人的にformなんかはとても難しいなと感じている。
とりあえず見てみましょう。
※私は見習いレベルなので、セキュリティーに関しては必ず読者の責任において対応してください。
※ここではあくまでも例示しているだけにとどめます。

---

```php:test.php
<form action="test2.php" method="POST">
    
    <textarea name="お問い合わせ内容" cols="50" rows="5"></textarea>

    <input type="hidden" name="ID" value=123>
    <input type="submit" value="送信">

</form>
```

---

こういった、よくあるformがある場合、読者はどのようなセキュリティを考えるでしょう。

---

例えば、
- XSS対策
かも知れません。
PHPでは、htmlspecialcharsという関数で対応します。

```php:test2.php
<?php
function h($string)
{
    return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}

var_dump (h($_POST["お問い合わせ内容"]));
```
はい、フォームのテキストはこれでなんとなくokそうですね。

では、formの他の部分はどうでしょう。
元のフォームでは、`<input type="hidden" name="ID" value=123>`で
valueをhiddenで送っています。

さて、*ブラウザのデベロッパーツールで色々いじってみましょう。*

---

もともと通常通りformで送ると以下の通りになります。
（いったんhtmlspecialcharsを省いてます。）
<img width="227" alt="スクリーンショット 2019-12-25 22.57.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/f764ddd0-5936-8b25-1b05-5b06a084411e.png">
問題なく送れてますね。
※このIDはなんでしょうか。顧客のIDでしょうか。
まあ、こんな感じでformのやり取りするのはまずい感じもしますが、まあ勉強用なので、ほっといてください。

---

では次に、デベロッパーツールをいじって送ってみましょう。
<img width="582" alt="スクリーンショット 2019-12-25 23.00.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/952ef4e8-358f-f191-943e-9eea184f0dac.png">
この部分を
<img width="512" alt="スクリーンショット 2019-12-25 23.00.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/2d627f9b-144b-45af-9085-b85e1e2852a2.png">
こうじゃ！

<img width="219" alt="スクリーンショット 2019-12-25 23.01.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/a4a63c55-0f15-0723-d616-d305da4bcf3f.png">
で、送れてしまった！

これでは、いけませんね。
PHPの場合、
例えば、POSTで送られてきたvalueをintに制限したり、
preg_matchde関数による正規表現を用いて、制限しないといけないかもしれません。

---

また、今回のformはtextareaです。
ここに記載する人が、改行等を入れるかもしれません。
例えば、
<img width="404" alt="スクリーンショット 2019-12-25 23.05.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/80b81b40-f3d2-3d8a-8788-1269104fd829.png">
このように改行を伴ったりスペースを伴う場合にこのレイアウトを崩さないようにしなければならないかもしれません。

---

また特殊文字を書かれたりした場合はどうでしょうか。
[ブリコルール](https://www.bricoleur.co.jp/blog/archives/4239)さんのサイトに
いろんなパターンが有りました。

通常では記入しない項目も記載してテストしたほうがいいでしょう。

---

さらに！ 
例えば、SQLを用いたTODOの場合、
先程のデベロッパーツールのところで
`DELETE FROM tebel;`
とか書かれたらどうなるのでしょうか・・・。（※５）

---

##セキュリティー以外にも。。。
大きな問題を起こすセキュリティー以外にも、
利用者が通常の操作で起こすような事項も確認するべきでしょう。
例えば、
- form送信を連打しても大丈夫か。
- データベースに数万件情報がある状態でも問題なく・遅滞なく利用できるか、
などです。

これらも、本来の機能とは異なる、非機能要件かもしれません。

---

今回のように、個人プロダクト等を行っている場合、目に見える「要件・機能」だけに
焦点を当てて制作を行いがちです。
しかし、セキュリティーを怠ると簡単にあなたのプロダクトは終わります。

勉強中の方にはすぐにとっつきにくい事柄だとは思いますが、
今回の記事の中で知らないことがあればぜひ一度調べて見てください。

アディオスアミーゴ！！

---

（※１）他に、ダルビッシュ有さんや、ウサイン・ボルトさん、石原さとみさん、北川景子さんといった、そうそうたるメンバーの生まれ年である。

（※２）[businessinsider.jp/人気プログラミング言語トップ10【2019版】](https://www.businessinsider.jp/post-202166)で、PHPは４位である。

（※３）GitHubでいうpull request。GitlabだとMerge Requestになる。

（※４）Create（生成）、Read（読み取り）、Update（更新）、Delete（削除）の頭文字。だいたいのWEBアプリが持っている機能である。

（※５）いわゆるSQLインジェクション。