athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

コードを自動生成して開発工数を減らした話

基幹システム開発グループの鉾田です。

当グループでは、「会員API」と言われているAPIを開発しています。 今回は、会員APIソースコードを自動生成することによって、開発工数を大きく減らした話をします。

会員APIとは

会員APIでは、アットホームにとってお客様にあたる不動産会社(以下、会員)の情報を扱っています。例えば以下のような情報です。

  • 企業名、連絡先、住所など会社としての基本的な情報

  • 契約しているサービスや、その利用状況

  • 全日本宅地建物取引協会や全日本不動産協会などの、会員が入会している業界団体情報

会員APIとは、上記のような会員情報を一元管理し、 登録や参照などの各種機能をWebAPIとして、様々なサービスや社内システムに対して提供する役割を持った仕組みのことです

機能改善や新規サービス開発のスピードを上げるために、2015年5月から始動しました。

会員APIアーキテクチャ

API自体は一般的に言われているMVCに近い形です。

f:id:mh06054:20160705102053p:plain

【Model】
* 業務ロジックを扱う層(Domain)

  • データベースアクセス層(Repository)

  • Domainとデータベースのオブジェクトをマッピングする層(DBModel)

【View】

  • JSONで出力結果を表現します。WebAPIなのでHTMLではありません。

【Controller】

  • リクエストを受け取り、Modelへ処理を委譲する層(Controller)

  • Viewへ出力する用のオブジェクトと、そのオブジェクトとDomainのマッピング(Response、Request)

これらに加えて、各層に対する単体テストと、結合テストがあります。

自動生成に至ったわけ。目的とねらい

簡単に言ってしまうと、機械的ではなく深く考える必要のある仕事に割く時間を増やしたいと思ったからです。

前述のとおり、会員APIは重要な役割を持っているシステムで、多数の機能を、ハイスピード・高品質で開発されることが望まれています。

そのような要望を満たすためには、リファクタや、より適したミドルウェアフレームワークへの変更、開発フローの改善など、深く考える必要のある仕事を多くこなし、それを継続する必要があります。

そのために、機械的な仕事の総量を減らす必要がありました。そして、機械的な仕事でウェイトが一番大きいと感じたものが、設計書があれば誰でも実装できるような、単純なコーディングでした。

しかし、単純であっても仕組みが大きいためコーディング量は多く、時間が掛かっていました。

(例)1つのテーブルに対するCRUD機能を持ったAPI実装でテスト込みで

  • 14ファイル

  • 約5700行

  • 約40hの工数

ここで、単純なコーディングには、多くの共通項があると気付きました。例えば

  • 主キーでの参照処理は殆どの場合で実装している

  • 登録・更新処理は扱うデータが違うだけで、フローは殆ど同じ など。

多くの共通項があるのであればソースコードは自動生成でき、自動生成できれば多くの単純なコーディングが無くなるはずだと考えました。

目標

現状、単純なコーディングと呼んでいる部分には、概ね1週間掛かっていたので、これらを2時間程度で終わらせられるようにすることを目標にしました。

自動生成せずに手動対応する部分は残ると思ったので、そこを含め自動生成していない部分の対応 -> テスト -> プルリク で2時間が限界だと思います。

自動生成のターゲット

  • あるテーブルに対しての登録・更新・削除(桁数チェックなど、DBカラムから必要と推測できるバリデーションを含む)

  • あるテーブルに対しての参照(条件を複数、AND、完全一致で指定できる(id=1、type1="1" and type2="3" など))

  • どの項目で紐づくのか示すことで、テーブルの親子構造にも対応する

  • もちろん親子構造は、登録・更新・削除・参照が、単一テーブルと同じレベルで処理できる

  • 自動生成される全てのコードに対する単体テストと、結合テスト

  • テストに必要なデータの生成処理

逆に、自動生成できるけど、コスパが悪い下記のような機能は自動生成しませんでした。

  • 参照に完全一致以外の条件を含める(<,>,!=など)。意外ですが、実績としてほとんど実装していないのです。

  • コード値に対する名前を取得するケースなどで必要となる、マスタの役割を持つテーブルとのリレーションを指定する機能(自動生成するための設定を書くぐらいなら、コードを書いたほうが早いと判断)

自動生成の仕組み

こういったケースではC#ならEntityFramework、RubyならRailsなどのフレームワークを使って解決するケースが多いのですが、それだと汎用性が高く人の手が介入する部分が多すぎるので、スクラッチで作ることにしました。

  1. 設定ファイルでどのテーブルに対するAPIを自動生成するか事前に設定し
  2. 自動生成実行
  3. テーブルの情報から導き出せる部分(項目名など)は導き出し、そうでない部分(参照の条件など)は設定ファイルから読み出しながら、 各種csファイルを生成する。このとき、自動生成していない部分は、TODOコメントで、任意で書き足す必要がある旨も出力する。
  4. 自動生成実行場所にまとめてアウトプット
  5. 会員APIプロジェクトに取り込む
  6. 取り込んだら、TODOを解消してテスト
  7. おわり

なお、自動生成の設計や実装面の話は、別の機会で説明したいと思います。カラム名からデータ型の推測や、項目名の名寄せなど、工夫を凝らしています。そのあたりの細かな工夫が、自動生成の質を高めています。

効果

開発者3名で合計274.5hを掛けて自動生成の処理を実装し、1ヶ月あたり約156h分の開発が削減できました。これは、現状開発に割り当てられる工数の約24%です。24%も改善できたので、今は案件処理がとても早くなりました。

単位あたりの目標としていた2時間もクリアでき、一つあたり1時間~2時間程度で実装が終わります。

今後は改善できた分の時間を、品質を上げたり、高性能にしたりするための施策に割り当てたいと思っています。

今後の課題

  • 自動生成そのものをテストしたほうがいいかもしれない。現状は、自動生成されたテストをレビューして正しいことを確認しているので、自動生成のコードも問題がないはず。ということにしています。
  • 自動生成するためのコードが複雑なので、メンテナンスが大変かもしれません。当然と言えば当然ですが、自動生成されるAPIを一からコーディングするよりは高い技術力が必要です。今のところは問題ないですが、このようなプログラムを書けるエンジニアを増やす必要があります。

おわりに

最近は要件定義やチームの進捗確認など、ディレクター的な役割が多かったので、久々にガッツリ開発できて楽しかったです。

エンジニアの醍醐味は、やっぱり技術をもって課題を解決することだと思いました。

改善前は業務効率が良くなかったので、比較的忙しいなかでのチャレンジでしたが、結果的には、楽しみながら24%業務効率が改善できたので大成功だと私は思っています。