社内システムを開発する際にAPIを使う、という選択肢を考える

# 社内システムとAPI

社内でとある雑談をしている際に、社内システムを構築する際にAPIを設計、開発するとより簡単、かつ疎結合なシステムを作る時に便利になってくるのではないか、という前提を元にAPIについて勉強しなおしました。

どうせ勉強するならアウトプットして外に出すことで間違っていた際にご指摘を受けることも出来ますし、自身の勉強の証にもなるだろうということでサクサクっと書いていきます。

# 参考図書

- [Webを支える技術](https://amzn.to/3jkMIMd)
- [Web API: The Good Parts](https://amzn.to/3i7W784)

# 学習の順番

- [Webを支える技術](https://amzn.to/3jkMIMd)
- [Web API: The Good Parts](https://amzn.to/3i7W784)

の順で勉強しました。

正確には[Webを支える技術](https://amzn.to/3jkMIMd)は読んだことがあったので、基本的な歴史や仕様について学び直すために読んだ、と言ったほうが正しいかもしれません。

そもそもHTTPとかを理解できていないとAPIについて何を言っているのか分からない、というのはあると思うのでWebの仕組みを理解する基礎固めのためにも読むべきだと思います。
あと単純に面白いです。

[Web API: The Good Parts](https://amzn.to/3i7W784)はWeb APIをこれから設計、開発しようという人を対象とした本なので、APIについてのざっくりとした説明はあるものの、主軸はあくまでこういうAPI設計したら気持ち悪くね？こっちの方がよくね？とか、特定のユーザーにAPI叩かれすぎたら困るよね？じゃあこうしよう！などの開発者向けの内容がメインです。

こちらも面白かったです。
オライリーの本ですが、著者が日本の方ということもあり、分かりにくい表現も少なく、スラスラ読める、という印象なので困っている方に特におすすめです。

# そもそもAPIって何よ？

## 一般的な定義

**Application programming interface**の略です。
よく言われるAPI、というのは大体の場合Web APIのことを指します。

なお、APIを使うことをITエンジニア界隈では「APIを叩く」、と言います。
これはAPIを使うことを英語で「hit api」というためで、それが和訳されて使われ続けて今に至るとか。

なお、Web APIとは、
[Web API: The Good Parts](https://amzn.to/3i7W784)
にある通り、

>Web APIとは「HTTPプロトコルを利用してネットワーク越しに呼び出すAPI」

と言ったような概念を指します。

この概念を図にすると、以下のようになります。

![スクリーンショット 2020-09-27 20.56.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/8ec99f97-c12a-c9ae-a9a5-dccac5345d92.png)

このようにHTTPプロトコルを用いてアクセスすることで、データをAPIサーバが返してくれるようになります。
なお、ここで返ってくるデータの形式はHTMLなどではなく、多くの場合JSONというデータ形式で返ってきます。
こちらのJSONを加工し、構築したフロントエンド上で表示することがほとんどでしょう。

## Twitter APIを用いたWeb APIの理解

もっと具体性を持たせるならば以下のようにも読み取ることが出来ます。

A君は重度のTwitter好きで、四六時中Twitterを見ています。

![sns_happy_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/98257ba0-1f52-6bb8-3835-80a8fb0dcf33.png)


既存のTwitterクライアントでは満足できなくなったA君は自分で考えた最強のTwitterクライアントを作りたいと考えました。

開発経験もあったA君は、試行錯誤をしていくうちにTwitterクライアントのフロントエンド、つまり画面を作り上げました。
しかしA君はTwitterからどうやってツイートなどのデータを取得するのか分かりませんでした。

![question_head_boy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/d62c7366-7793-d8b9-eed1-aa54c00f745f.png)

そこで調べていくうちにTwitterはWeb APIを公開しており、きちんとした利用手続きを踏み、[公式ドキュメント](https://developer.twitter.com/en/docs/api-reference-index)に沿ってURIをHTTPリクエストすればタイムラインなどが公式から取得できることが分かりました。

これが以下のようなイメージです。

![スクリーンショット 2020-09-27 21.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/ea4ffb1c-d387-5a52-c8a1-068cf1eeb31a.png)


このようにAPIを公開することでタイムラインの取得やユーザー情報の取得など、Twitterが提供しているサービスを中身を意識せずに活用できるようになるわけです。
この結果、A君は大好きなTwitterをさらに使いやすく活用することに成功しました。
そしてA君のTwitterクライアントは他のTwitterユーザーからも好評で、さらにTwitterの利用者数が上がったため、Twitter社も嬉しい。いわゆるWin-Winの関係が出来上がるわけです。

こういったような、APIを公開することで外部システムとの連携を容易にし、更なる価値を生み出すことで生まれるサービスなどの発展のことをAPIエコノミーと言います。
ただ、今回は社内システムを構築する上でのAPIの認識のため、このようなケースは想定しないものとして考えます。

# 社内システムでAPIを使うメリット

では、いわゆる公開するためのAPIではなく、社内システムなどのクローズドなシステムでAPIを使うメリットとは何なのでしょうか。

## 疎結合なシステムを構築できる

これが社内システムでAPIを使う最も大きなメリットでしょう。
社内システムというのは各部署がそれぞれの業務をシステムに落とし込む、いわゆる一気通貫型のシステムが乱立しているケースが多いと思います。
しかし、このケースだと多くの場合、それぞれのシステムが密接に連携している、いわゆる密結合となっており、一つのシステムで不具合が発生した際に他のシステムに影響を及ぼしてしまうことがあります。

しかし、APIを使うことでそれぞれのシステムがAPIを介してデータのやり取りを行うことでそれぞれの連携を防ぐ、即ち疎結合となります。
つまり、一つのシステムが他のシステムへの影響を少なくでき、独立性の高い状態を維持できるようになります。
これは障害対応を行う、保守を行う際に非常に大きな点です。

また、マイクロサービス化が行える、という点もメリットです。
一つのサービスを構築する際にそれぞれの機能を分割して開発し、APIを通して連携することで細かい機能単位で独立してデプロイを行うことが出来たり、モバイルアプリを開発しなければならない際にも画面を作り、データのやり取りをするときはAPIを叩く、といったようなデバイス毎に開発の多様性が生まれます。

##再利用性が高まる

システムの大部分は特定の共通の処理（ログインや社員データの受け取りなど）をある程度行った上で、その上に業務を代替するための独自の処理が行われる、というものがほとんどです。

ということは、システムの共通処理をAPIとして叩けるようにしておくことは開発の工数を減らすことに繋がります。
また、同じ処理を行う場合でも特定のAPIに依存しておくことで、ミスを行ってしまいがちな部分を限りなく少なくすることができます。

そういう文脈でいうならば、設計、開発する際にいわゆる美しいAPIを設計することで再利用性が高まっていくため、大きなメリットを享受できます。


※設計の美しいAPIは、使いやすい、変更しやすい、頑強である、恥ずかしくないという考えのこと。

# 社内システムでAPIを設計する上で注意すべきセキュリティ要件

社内システムを構築する上でもっとも留意すべき点の一つでしょう。
いわゆる一般的なWeb APIと異なり、そこまで不特定多数のアクセスはされないといえども、注意して設計するに越したことはありません。

## プロトコルでの対策

HTTPを使うもの、とこれまでは説明してきましたが、それだけで暗号化の仕組みなどを持ちません。
即ち、悪い人がデータの中身を盗み見しようとすれば簡単に見れてしまいます。

そこで、HTTPSを使う、というものが効果的だと考えられています。
HTTPSはTLSによる暗号化を採用したプロトコルで、URIのパス、クエリ文字列、そしてヘッダとボディが暗号化されるため、一連のやり取りにおけるほとんどの情報が傍受できなくなります。

ただし、HTTPSを使えば必ずしも安全かというとそうではありません。
社内システムで使うような場合は一般人からのアクセスは考えにくいものとなるのでほとんど安全ですが、セキュリティの概念としてどういったリスクが考えうるかということを知っておくことは大事なので、書いておきます。

過去の事例を挙げるならば、OpenSSLというオープンソースの暗号化ライブラリのバグによるもの、クライアントの不十分な対策による中間者攻撃(MITM)、そしてそもそも証明書を発行する認証局が攻撃を受け、偽の証明書を発行してしまう、といったものが挙げられます。

これらの事例はたとえどんな対応を行ったとしても100%堅牢性を保つことは難しく、そして常に最新の情報をキャッチアップしていく必要なことが窺えます。


## ブラウザからのアクセスへの対策

APIに限った話ではありませんが、以下の攻撃方法への対応策は十分に行っておくべきだと考えられています。

- [XSS](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)
- [XSRF](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA)
- JSONハイジャック

とりわけ、ブラウザは汎用的で多機能、そして利用者が圧倒的に多いためにきちんと対策されていないAPIに対して悪意を持った攻撃をする人が少なからず存在しているため、優先度の高いセキュリティ要件となっています。

## 悪意あるユーザへの対策

ユーザの中にはAPIサーバへのリクエストで脆弱性をつくような、設計者側が想定していないようなリクエストを送ることで自身の利益となるような処理を行わせたりします。

これまでの例と異なる点は、きちんと認証を行った上で利用しているユーザが脆弱性を突こうとしている点です。
一般的な認証機能を実装し、外部からの対策をしたとしても、きちんと手順を踏んだユーザが悪意を持っているケースも想定されます。ただし、今回の社内システムにおいてはこのケースは認証自体が社内の人間しか通さないように設計されているため、そこまで考慮する必要がありません。その為、気になる方は[Web API: The Good Parts](https://amzn.to/3i7W784)を買ってください。


## HTTPヘッダでの対策

HTTPヘッダの中にはセキュリティ強化のために各ブラウザで設定されているヘッダが存在します。
これらはRFC(Request for comment)などの公式で定義されているわけではありませんが、有用性のために今日でも広く使われています。

- X-Content-Type-Options
- X-XSS-Protection
- X-Frame-Options
- Content-Security-Policy
- Strict-Transport-Security
- Public-Key-Pins

## クッキーでの対策

ブラウザでセッションを扱う場合、クッキーを使うことが多いでしょう。
その際には、以下のようにset-Cookieを行う際にSecureとHttpOnlyを設定することでより堅牢になります。

```
Set-Cookie: session=e9e9769e8a9697e697ae696c98d89878; Path=/; Secure; HttpOnly 
```

Secure属性は設定することでHTTPS通信の時のみクッキーがサーバに送り返されます。
そして、HttpOnly属性はHTTPの通信のみでクッキーが使われ、ブラウザでJavaScriptなどを使ってアクセスできないようにする、というものです。即ち、XSSなどでの攻撃に対しての直接的な対策になります。


## アクセス制限

こちらも認証をした上で攻撃をできないようにする、という条件を持つ社内システムでは重要度が低いため、気になる方は書籍の購入をお薦めします。



# 最後に

ここまでAPIについてや、使うメリット、設計する上で留意すべきセキュリティ要件など、かいつまんで説明しました。

社内システムでAPIを用いる場合、システム自体の独立性を高める(疎結合)ことで、様々なメリットを享受できる一方で、多様なセキュリティ要件に気を使わなければならない、という点も挙げられます。
一長一短あるのでそれぞれの要件に見合ったシステム開発を進めていくべきでしょう。