こんにちはsekitakaです。

serverlessな環境での開発も随分慣れてきましたが、コードの再利用性についてどうしようか悩んでいるので考えたこと&暫定結論を公開します。
ベストプラクティスを模索中なのでコメントでの議論も大歓迎です。

前提条件

共通するDynamoDBのテーブル(例:User)を参照する3つのプロジェクトがある。

  • プロジェクトP1
  • プロジェクトP2
  • プロジェクトJ1

以下のような状況になっている。

  • プロジェクトP1には既にUserデータのデータを取得する関数がある
  • プロジェクトP1,P2はPythonで実装されており、プロジェクトJ1はJavaScriptで実装されている。
  • プロジェクトは全てLambda関数郡としてデプロイされる。

お題

Userテーブルからのデータ取得を各プロジェクトに組み込むにはどんな方法がよいか考える

案1 - 車輪の再発明を恐れない

各プロジェクト内にUserテーブルからのデータ取得用のライブラリをそれぞれ作成する。
この方法は再利用性がプロジェクト内に限定されるかわりに、各プロジェクトで行った修正が他のプロジェクトへ影響しない。
PythonとJavaScriptの両方の言語で実装する必要がある。

案2 - Userテーブル専用のLambda関数を作成する

データアクセス専用のLambda関数を作成する。
1種類の言語でのみデータアクセス用のLambda関数を実装すればよい。
ただしデータアクセス関数を変更した場合、全プロジェクトに影響範囲が広がる。
つまりデータアクセス関数を変更した場合に、各プロジェクトのテストを実行する仕組みが必要になる。

案3 - Userテーブル専用のAPIを作成する

API Gatewayに専用APIを作る。案2とあまり変わらないが、APIGatewayのバージョン管理が使用できそう。
各プロジェクトからバージョン指定でAPIを実行することで、バージョンアップに伴う影響範囲を小さく出来る。

案4 - プロジェクトP1の既存の関数を使用する

案2と似ている。プロジェクトP1の変更がプロジェクトP2,J1に影響するという構造になり混乱が生じやすい気がする。

案5 - 各言語のライブラリを作る

案1に似ているがPythonとJavaScriptの2種類のライブラリを汎用で作成する方法もある。
利用するプロジェクトではnpmのプライベートリポジトリなどを利用して依存関係を解決する。
適切にバージョン管理すれば、バージョンアップに伴う影響も最小限に抑えることができる。

比較

コード量

類似コードを記述(コピペ)する量を比較します。
その場のスピードを出すために案1を使いたいこともありますが、プロジェクトが増えることを考えるとあまりよくないかな。
ただAWSのSDKとして既にライブラリ化されているので、それを利用する部分のコードだけと考えると無くもないかな。

倍率
案1 3(プロジェクトごとに増える)
案2 1
案3 1
案4 0(既存なので)
案5 2(言語毎に増える)

実装規模

新しく開発する必要のある部分の開発工数の比較。

規模
案1
案2
案3
案4
案5

シンプルさ

全体の構造が分かりやすいほどトラブルが起こりにくいので、シンプルさも大切です。

シンプルさ
案1
案2
案3 △(案2よりAPI Gateway分複雑)
案4 ×
案5 ○(作るの大変だけど使うのはシンプル)

点数化

比較したけど何がいいかわからないので点数化してみました。
各要素3点満点にしました。点数が高いほどよい評価です。

倍率 規模 シンプルさ 合計
案1 1 3 3 7
案2 3 2 3 8
案3 3 2 2 7
案4 3 3 1 7
案5 2 1 3 6

ザルみたいな点数化ですが差がつきました。案2がよさそうです。
感覚的にも案2のシンプルなわかりやすさはいい感じに思えます。

とりあえずの結論

案2がよさそうという結論になりました。
他にも方法がありそうでしたらコメントお願いします!

まとめ

1つのモノリシックなアプリを作るのでなく、既存のリソースを利用する場合リソースにどう再利用するか悩みどころが多いですね。
今回の結論も絶対ということはなくスピードや移行コストを考えるとまた違う結論になりそうです。

ノウハウ共有というより脳内垂れ流しですが、色々コメントいただけるとありがたいです。