API開発を支える可視化ツールをMVPとして作っている話

この記事は[リクルートライフスタイル Advent Calendar 2018](https://qiita.com/advent-calendar/2018/recruitlifestyle)の21日目の記事です。
わりと他のみんながガチガチな本気記事投稿しているので、仕事のスキマ時間や趣味の延長でやっている小ネタについて書いていきたいと思います。

## はじめに
どうも改めまして、ホットペッパービューティでAPI開発をしている @tacumai です。
ぼくは2年ほど社内でインフラエンジニアし、3年目になる今年はJavaをゴリゴリ書くアプリケーションエンジニアをさせていただいております。僕自身、インフラのas Code化をしたり、運用の自動化したりと、社内では日々ヌクモリ運用によって起こり得る本番障害を減らすべくいい感じのDevOpsな取り組みをしていったのですが、アプリケーション開発に移ると、新たにアプリレイヤの課題があることに気づきました。

## ある日、こんな課題を感じた
これまで

- [Spring + Railsによるサービス分割の取り組み](https://engineer.recruit-lifestyle.co.jp/techblog/2017-02-17-spring-rails/)
- [ホットペッパービューティーのAndroidアプリをリプレイスしました](https://engineer.recruit-lifestyle.co.jp/techblog/2018-03-22-hpb-android-replace/)

でみられるようなマイクロサービス化・システムリプレイスをホットペッパービューティでは行なってきました。そしてそれは今でも現在進行中の形で進んでいます。しかし、APIの数が増えるも、どのAPIがどのデータベースのどのテーブルに対して、参照・更新しているのかわからず、リプレイス時には既存の複雑なコードを読むことに多大な苦労をせざるを得ない状況でした。

## こういうものを作りたい
めんどくさがりマンのぼくは、コードを読みながら猛烈に「なんかいい感じにこのリポジトリのURLを入力してくれたらどのエンドポイントがどのController/Service/Repositoryを経由し、どのテーブルにアクセスしているのかすぐにわかるようになってくれないかなぁ」と思う毎日でした。とまぁ、そんな都合の良いツールは社内には存在せず、絶望しました。

そして、おもったのです。

「「「「「「 つくればよいのでは? :thinking: 」」」」」」




### まずはMVPを定義するぞ
「リポジトリのURLを入力してくれたらどのエンドポイントがどのController/Service/Repositoryを経由し、どのテーブルにアクセスしているのかがすぐにわかるツール」をつくるために、やらなければいけないこと（やれたらいいなとおもうこと）を整理すると、膨大にあることに気づいたので、大まかに最低限何をやらなければならないのか、整理しました。そして

1. Javaのコードを読み込み、SQLファイルがどのエンドポイント（コントローラ）に紐づいているか求めるパーサ・分析ツールが必要
2. 1の作業を終えたあと、構造化してファイルに保存する必要がある
3. 構造化ファイルを読み込み、ビジュアライズする必要がある

で出来そうだなと思い、ステップを分けました。

なお、これは「仕事」ではありません。あくまで「自分が楽したい（他の人も楽できる）ツールをとにかく作りたいんだ」という気持ちで始めた趣味ツールなので、手間をかけたくありません。実際に動くものを作り、価値があるとおもったら手間暇かけて作り込めればいい。なので `1. Javaのパーサ・分析` については難易度が高く、そしてコスパが悪いので今回はやらないという判断をしました。さらに、内部実装まで分析できると嬉しいですが、より難易度が高いはずなので、まずはエンドポイントだけを考えることにしました。また可視化についても、かっこいいスマートでよさげなFWをつかったアレコレも考えず、学習コストなしですぐに使える jQueryを使って実装を始めました。

### 構造を定義
まずは構造の定義を。Javaコードを分析すると、おそらくこんなコードが生まれるであろう、という成果物を自分で定義。
アプリケーション・個々のAPI・DBについて、構造化できればよいな、と判断し、以下のようにまとめてみました。

``` appcation.json
// API単位の情報を管理するJSONファイル
{
  "fuga-api": {
    "repository-url": "https://github.com/hoge/fuga-api",
    "detail": "ユーザ向けリソースAPI",
    "languages": [
      "Java",
      "Groovy"
    ],
    "frameworks": [
      "Spring-Boot"
    ]
  }
}
```


``` api.json
// アプリ単位の情報を管理するJSONファイル
{
  "title": "予約取得API",
  "belongsTo": "fuga-api",
  "http": {
    "endpoint": "/reservations/{id}",
    "method": "GET"
  },
  "db-requests": [
    "development1": {
      "scheme": "ADPHPD",
      "tables": {
        "STORES": [
          "ID",
          "NAME",
          "CREATED_AT",
          "UPDATED_AT"
        ],
        "USERS": [
          "ID",
          "NAME",
          "UP_DATE",
          "CREATED_DATE"
        ]
      }
    }
  ]
}
```


``` db.json
// DBの情報
{
  "SCHEME1": {
    "detail": "カスタマ向けテーブルスキーマ",
    "tables": {
      "users": {
        "ID": {
          "type": "int",
          "primaryKey": true,
          "index": true
        },
        "NAME": {
          "type": "varchar(30)"
        },
        "CREATEAT_AT": {
          "type": "DATE"
        },
        "UPDATED_AT": {
          "type": "DATE"
        }
      }
    }
  }
}
```

### 可視化してみる
JavaScriptの `canvas` 機能を使って、事前に準備したJSONファイルを読み込み、以下のような可視化を行なってみました。

<img width="980" alt="sample2.png" src="https://qiita-image-store.s3.amazonaws.com/0/34144/507c1543-615c-8667-ff25-2788a713e127.png">



個人的にはもっといい感じにしたいぞ！という気持ちが実装中からめちゃくちゃ溢れてきましたが、一旦、「JSONファイルさえ書いて読み込めば、APIごとのテーブル参照が一目瞭然でわかる」という状態に持っていくことができました。JSONファイルを増やしていけば、情報的には、当初求めていたニーズを満たすことができます。


### 今後
「MVP」としての形には持っていくことができましたが、これでは運用もできないし、他のアプリケーションとの連携もまだ難しい状態です。次の頑張りどころは、Javaのパーサまたはビジュアライゼーションの部分ですが、見た目がよいほうが改善も頑張れるので、今のこの四角形で面白みのないcanvas描画を、別のツールなりで置き換えてよさげな感じにすることを目標に改善を進めたいと思います。

以上、みなさま良いお年を！ :sparkles: