0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

クラウド引越し準備:FaaSコードとクラウドインフラの分離をしていつでもクラウドを乗換可能に

Posted at

AWSってお値段たかいよね他のサービスに載せ替えできないの?といわれたときに

注意:この記事はAIが作成しています
参照元の存在、参考元のリンクの信頼度、事実の歪曲がないかをAIによりセルフチェックしています

課題:クラウドに縛られるコード

FaaSアプリケーション開発でよくある問題は、最初からAWS Lambda専用、Azure Functions専用でコードを書いてしまうことです。これだと後でクラウドを変えたくなった時に大変です。

解決策:ソースコードとハンドラーを分離

基本的な考え方は単純です:

  1. ビジネスロジック:クラウドに依存しない純粋なコード
  2. ハンドラー:各クラウド専用の薄いラッパー
  3. デプロイ時に組み合わせる

実装の考え方

1. ビジネスロジックは純粋関数で

// core/userService.ts(どのクラウドでも同じ)
export function createUser(userData: any) {
  // バリデーション
  if (!userData.email) {
    return { error: 'Email required', status: 400 };
  }
  
  // ビジネスロジック
  const user = processUser(userData);
  return { user, status: 201 };
}

2. ハンドラーは薄いラッパーに

AWS Lambda用

export const handler = (event) => {
  const result = createUser(JSON.parse(event.body));
  return { statusCode: result.status, body: JSON.stringify(result) };
};

Azure Functions用

export default function(context, req) {
  const result = createUser(req.body);
  context.res = { status: result.status, body: result };
};

3. プロジェクト構造

src/
├── core/              # 共通ビジネスロジック
│   └── userService.ts
├── config/            # 関数マッピング設定
│   └── functions.ts
├── handlers/          # 各クラウド用ハンドラー
│   ├── aws.ts
│   ├── azure.ts
│   └── gcp.ts
└── tests/             # 共通テスト

または、各関数を個別のハンドラーファイルにする方法もあります:

src/
├── core/              # 共通ビジネスロジック
│   └── userService.ts
├── handlers/
│   ├── aws/
│   │   ├── createUser.ts    # createUser専用ハンドラー
│   │   └── updateUser.ts    # updateUser専用ハンドラー
│   └── azure/
│       ├── createUser.ts
│       └── updateUser.ts
└── tests/

デプロイ戦略

ビルド時にハンドラーを選択

package.jsonスクリプト例

{
  "scripts": {
    "build:aws": "webpack --config webpack.aws.js",
    "build:azure": "webpack --config webpack.azure.js", 
    "build:gcp": "webpack --config webpack.gcp.js",
    "deploy:aws": "npm run build:aws && serverless deploy",
    "deploy:azure": "npm run build:azure && func azure functionapp publish"
  }
}

ローカル開発の統一

開発時は普通のWeb APIとして実行

// local/server.ts
import express from 'express';
import { createUser } from '../core/userService';

const app = express();
app.post('/users', (req, res) => {
  const result = createUser(req.body);
  res.status(result.status).json(result);
});

これで開発時は npm start で普通にテストできます。

メリット

FaaS以外のサービスでも応用可能

この考え方はFaaSに限らず、他のクラウドサービスでも活用できます:

  • データベース:SQL文を共通化し、接続部分だけをクラウド固有に(MySQL、PostgreSQL、Cloud SQLなど)
  • ストレージ:ファイル操作ロジックを共通化し、APIアダプターを分離(S3、Blob Storage、Cloud Storageなど)
  • メッセージキュー:メッセージ処理ロジックを共通化し、キュー接続部分を分離(SQS、Service Bus、Pub/Subなど)
  • コンテナ:Dockerイメージは同じで、オーケストレーション設定だけを変更(ECS、AKS、GKEなど)

まとめ

要点は3つだけ:

  1. ビジネスロジックはクラウドに依存させない
  2. ハンドラーは各クラウド専用の薄いラッパーにする
  3. デプロイ時に適切なハンドラーと組み合わせる

この設計により、コードの大部分を変更することなく、いつでも好きなクラウドサービスに乗り換えることができます。最初からこの構造で作っておけば、後で「AWSが高くなったからGCPに移りたい」となった時も安心です。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?