PR

BFF(Backend for Frontend)を基礎から理解する – AWSでの実装付き解説 –

アーキテクチャ
記事内に広告が含まれています。

フロントエンドとバックエンドの連携が複雑になっている。最近、そんな課題に直面する機会が増えてきました。

フロントエンドから複数のAPIを呼び出したり、画面に応じて必要なデータ構造が変わったりすると、バックエンド側にどんどん処理が追加されてしまい、いつの間にか役割が肥大化していることもあります。

自分も実際に、そうしたつなぎ込みの難しさや、処理の整理がうまくいかない状況に悩んできました。そんな中で注目したのが「BFF(Backend for Frontend)」という設計パターンです。

本記事では、BFFの基本的な考え方から、なぜ今このアーキテクチャが有効なのか、さらにAWS上でのシンプルな実装例までを丁寧に解説します。

自分と同じように、フロントエンドとバックエンドの連携に課題を感じている方のヒントになれば幸いです。

想定読者
  • フロントエンドとバックエンドのつなぎ込みに課題を感じている方
  • バックエンドの責務が肥大化していることに悩んでいる方
  • BFFという言葉は聞いたことがあるが、実際の使い方が分からない方
  • アーキテクチャ設計に興味があり、AWSで実践してみたい方
得られるメリット
  • BFF(Backend for Frontend)の基本的な考え方と導入理由を体系的に理解できます
  • フロントとバックエンドの役割分担の整理や構成のヒントを得られます
  • AWSを使ってBFFを構築する具体的な方法を学べます
  • 実体験を踏まえたリアルな課題とその解決方法を知ることができます
  1. BFFを含むアーキテクチャパターンを体系的に学べるおすすめ書籍
  2. はじめに:BFF導入に至った背景と目的
  3. BFF(Backend for Frontend)とは?初心者にもわかる基本解説
  4. なぜBFFが必要なのか?導入メリットとよくある課題
    1. よくある課題
      1. 1. フロントから複数のAPIを呼び出す煩雑さ
      2. 2. バックエンドの肥大化・責務の混在
      3. 3. UIごとに必要なデータ構造の違い
    2. BFF導入のメリット
    3. こんなときBFFが有効
  5. BFFのアーキテクチャパターンと技術選定
    1. BFFの基本構成パターン
    2. API Gatewayとの併用
  6. 【実践】AWSでBFFを構築する方法(ステップ・バイ・ステップ)
    1. 使用するAWSサービスと構成
    2. プロジェクトの構成
    3. ステップ1:プロジェクトの準備
    4. ステップ2:Lambdaハンドラの実装(app.js)
    5. ステップ3:AWSにデプロイ
    6. 動作確認
    7. 最後に
  7. FAQ:BFF(Backend for Frontend) × AWS SAMに関するよくある質問
    1. BFF(Backend for Frontend)ってそもそも何ですか?
    2. API Gatewayだけじゃダメなんですか?
    3. マイクロサービスと何が違うの?
    4. いつBFFを導入するべきですか?
    5. デメリットはありますか?
    6. API Gateway のステージ名が Prod になっているのはなぜですか?
  8. 参考資料とリソース:BFFのさらなる学習のために
    1. BFFを含むアーキテクチャパターンを体系的に学べるおすすめ書籍
    2. リソース
  9. まとめと今後の活用方法:BFFを効果的に活用するために
    1. 今後の活用アイデア

この書籍では、BFFを含むモダンなアーキテクチャパターン(API Gateway、サービス分離、境界づけられたコンテキストなど)を体系的に解説しています。
特に以下のような方におすすめです:

  • マイクロサービスとBFFの関係をもっと理解したい
  • アーキテクチャ設計の「なぜそうするのか」を知りたい
  • フロントとバックエンドの責務分離をどう進めるべきか悩んでいる

実践的なシナリオや設計思想が詰まっており、アーキテクチャに関わるエンジニアにとって即戦力となる一冊です。

広告

アプリケーション開発において、フロントエンドから複数のバックエンドAPIを直接呼び出す構成を取っていたところ、徐々に限界を感じるようになりました。

例えば、画面ごとに必要なデータを揃えるためにフロント側の処理が複雑になり、APIの呼び出し回数も増加。その一方で、バックエンドはその都度「フロントで使いやすいように」とロジックを追加していった結果、次第に責務が曖昧になり、保守性が低下していく問題にも直面しました。

こうした課題を解決するために注目したのが、BFF(Backend for Frontend)というアーキテクチャパターンです。BFFは、UIごとに最適化されたバックエンドを構築するという考え方で、複数のAPIを集約・整形してフロントエンドに渡す「中間層」として機能します。

本記事の目的は、フロントエンドとバックエンドのつなぎ込みに関する実体験を踏まえながら、BFFというアーキテクチャパターンの基礎理解と実践的な導入方法を整理することです。

BFF(Backend for Frontend)とは、特定のフロントエンド(Web、モバイルアプリなど)に最適化されたバックエンドを構築するアーキテクチャパターンです。

Microsoftのページによると、以下のように記載があります

当初、デスクトップ Web UI と対応するバックエンド サービスを使用して設計されたアプリケーションについて考えてみましょう。時間の経過とともにビジネス要件が変化するにつれて、モバイル インターフェイスが追加されました。両方のインターフェイスは同じバックエンド サービスとやり取りしますが、モバイル デバイスの機能は、画面サイズ、パフォーマンス、および表示制限の点でデスクトップ ブラウザーとは大きく異なります。

https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontendsより引用

インターフェイス固有の要件のみを処理する新しいレイヤーを導入します。このレイヤーは、バックエンド フォー フロントエンド (BFF) サービスと呼ばれ、フロントエンド クライアントとバックエンド サービスの間に配置されます。アプリケーションが複数のインターフェイスをサポートしている場合は、インターフェイスごとに BFF サービスを作成します。たとえば、Web インターフェイスとモバイル アプリがある場合は、それぞれに個別の BFF サービスを作成します。

https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontendsより引用

モバイルとWebでは画面サイズ、パフィーマンス、表示制限が異なる。インターフェイス固有の要件のみを処理する新しいレイヤーを導入します。

フロントエンドとバックエンドの間に配置され、インターフェイスごとにBFFサービスを作成します。

アプリケーションのフロントエンドとバックエンドの接続が複雑になるにつれ、設計上の課題が顕在化してきます。私自身、フロントエンドから複数のAPIを直接呼び出す構成を取っていた際に、いくつかの問題に直面しました。

ここでは、そうしたよくある課題と、それに対するBFF導入のメリットを紹介します。

よくある課題

1. フロントから複数のAPIを呼び出す煩雑さ

  • 複数のバックエンドサービスに個別でリクエストを投げる必要がある
  • データの整形や結合がフロント側の責任になり、実装が複雑化
  • 複数APIの呼び出しに伴うネットワーク遅延、エラーハンドリングの分散

2. バックエンドの肥大化・責務の混在

  • 「UIに必要な形式で返してほしい」という要件が追加され、サービス層が肥大化
  • 表示用のロジックがビジネスロジックと混在し、責務が曖昧に
  • 保守性・再利用性が下がる

3. UIごとに必要なデータ構造の違い

  • Webとモバイルで同じAPIを使っても、必要な項目や頻度が違う
  • 結果としてフロントが「もらったデータをどう使うか」に悩む

BFF導入のメリット

メリット説明
UIに最適化されたレスポンスWeb、モバイルなどそれぞれのUIに合わせたデータ構造で返せる
データの集約と整形複数のマイクロサービスから取得したデータを統合して返す処理をBFFに集約できる
責務の分離ビジネスロジックと表示用のロジックを分離でき、バックエンドの設計がシンプルになる
保守性・拡張性の向上UI変更時の影響を最小限に抑えられ、将来的な改善も柔軟に対応可能

こんなときBFFが有効

  • マイクロサービス構成で、フロントから呼び出すAPIが複数に分かれている
  • 複数のUI(Web, モバイル, タブレット)を提供している
  • バックエンドの責務が肥大化していて整理したい
  • フロントとバックの開発チームが分かれていて、API連携の仕様調整が大変

BFFを導入するにあたっては、どのようにアーキテクチャを設計し、どの技術を使うかが重要です。ここでは、BFFにおける典型的な構成パターンと、それを実現するための技術選定のポイントを整理します。

BFFの基本構成パターン

BFFは「UIとバックエンドサービスの間に立つ中間層」として配置され、以下のような構成になります。

API Gatewayとの併用

BFFはAPI Gatewayと併用されることも多く、以下のような構成が確認できます。

  • API Gateway:認証・ルーティング・レート制限などを担当
  • BFF:データ整形・集約・UI最適化を担当

使用するAWSサービスと構成

  • API Gateway:フロントからのリクエスト受付
  • AWS Lambda:BFFとして動作(Node.js + Express)
  • モックバックエンドAPI:JSONPlaceholder の外部API(https://jsonplaceholder.typicode.com/)

プロジェクトの構成

bff-sam/
├── template.yaml              # SAM テンプレートファイル(CloudFormation)
├── events/
│   └── event.json             # テスト用のリクエスト(ローカルテスト用)
├── src/
│   └── app.js                 # Lambda ハンドラ関数(BFFロジック)
├── package.json               # Node.js パッケージ定義(axiosなどを管理)
└── README.md                  # プロジェクト説明(任意)

ステップ1:プロジェクトの準備

1.GitHubのリポジトリを作成します

% gh repo create bff-on-aws --public --clone
✓ Created repository XXXXX/bff-on-aws on GitHub
  https://github.com/XXXXX/bff-on-aws
% gh repo view XXXXX/bff-on-aws
XXXXX/bff-on-aws
No description provided

This repository does not have a README

View this repository on GitHub: https://github.com/XXXXX/bff-on-aws
% 

2. Cursor「フォルダーをワークスペースに追加」をクリックし作成したリポジトリ(フォルダ)を追加します

ステップ2:Lambdaハンドラの実装(app.js)

1. srcフォルダを作成します

2. app.jsを作成します

const axios = require("axios");

exports.handler = async (event) => {
  try {
    const [postsRes, usersRes] = await Promise.all([
      axios.get("https://jsonplaceholder.typicode.com/posts"),
      axios.get("https://jsonplaceholder.typicode.com/users"),
    ]);

    //
    console.log("postsRes sample:", postsRes.data.slice(0, 1));
    console.log("usersRes sample:", usersRes.data.slice(0, 1));

    const usersMap = new Map(usersRes.data.map(user => [user.id, user.name]));

    const combined = postsRes.data.map(post => ({
      id: post.id,
      author: usersMap.get(post.userId) || "Unknown",
    }));

    return {
      statusCode: 200,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(combined)
    };
  } catch (error) {
    console.error(" Lambda error:", error);
    return {
      statusCode: 500,
      body: JSON.stringify({ message: "Internal server error" })
    };
  }
};

3. template.ymlファイルを作成します

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  AWS SAM template for BFF (Backend for Frontend) demo.
  Aggregates /posts and /users from JSONPlaceholder.

Globals:
  Function:
    Timeout: 10
    Runtime: nodejs18.x
    Architectures:
      - x86_64

Resources:
  BffFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.handler
      CodeUri: src/
      Description: BFF Lambda Function that aggregates posts and users
      MemorySize: 128
      Events:
        Api:
          Type: Api
          Properties:
            Path: /posts-with-users
            Method: get
            Auth:
              AuthorizationType: NONE      

Outputs:
  BffApiUrl:
    Description: "API Gateway endpoint URL for BFF function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/posts-with-users"

4./srcディレクトリで依存パッケージをインストールします

bff-on-aws % cd src       
src % npm init -y

Wrote to /Users/XXXXXX/Documents/cursor/bff-on-aws/src/package.json:

{
  "name": "src",
  "version": "1.0.0",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.8.4"
  },
  "devDependencies": {},
  "description": ""
}



src % npm install axios

up to date, audited 24 packages in 824ms

6 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
src % 

5. ビルドします

src % cd ..
bff-on-aws % sam build

        SAM CLI now collects telemetry to better understand customer needs.

        You can OPT OUT and disable telemetry collection by setting the
        environment variable SAM_CLI_TELEMETRY=0 in your shell.
        Thanks for your help!

        Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html

Building codeuri: /Users/XXXXXX/Documents/cursor/bff-on-aws/src runtime: nodejs18.x architecture: x86_64 functions: BffFunction                    
package.json file not found. Continuing the build without dependencies.                                                                               
 Running NodejsNpmBuilder:CopySource                                                                                                                  

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided

SAM CLI update available (1.136.0); (1.134.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html
bff-on-aws % ls -lR .aws-sam
total 8
drwxr-xr-x@ 4 XXXXX  YYYYY  128  3 30 16:09 build
-rw-r--r--@ 1 XXXXX  YYYYY  348  3 30 16:09 build.toml

.aws-sam/build:
total 8
drwxr-xr-x@ 3 XXXXX  YYYYY   96  3 30 16:09 BffFunction
-rw-r--r--@ 1 XXXXX  YYYYY  895  3 30 16:09 template.yaml

.aws-sam/build/BffFunction:
total 8
-rw-r--r--@ 1 XXXXX  YYYYY  995  3 30 16:01 handler.js
bff-on-aws % 

ステップ3:AWSにデプロイ

1.事前にSSOサインインしておきます

bff-on-aws % aws sso login --sso-session XXXXXXX
bff-on-aws % export AWS_PROFILE=XXXXXXX
bff-on-aws % aws sts get-caller-identity        
{
    "UserId": "XXXXXX",
    "Account": "XXXXXX",
    "Arn": "arn:aws:sts::XXXXXX:assumed-role/XXXXXX/XXXXX"
}
bff-on-aws % 

2. 実行します

bff-on-aws % sam deploy --guided                       

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: bff-sam-demo
        AWS Region [ap-northeast-1]:               
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: y
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: N
        BffFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: Y
        SAM configuration file [samconfig.toml]: 
        SAM configuration environment [default]: 

        Looking for resources needed for deployment:
        Creating the required resources...
        Successfully created!
オプションまとめ
質問意味入力例
Stack NameCloudFormationスタックの名前(このプロジェクトを識別する名前)任意
AWS Regionデプロイ先のリージョン任意
Confirm changes before deploy実際に変更を加える前に確認(Changeset)を表示するかy
Allow SAM CLI IAM role creation必要なIAMロールが無ければSAMが自動で作っていいかy
Disable rollbackデプロイ失敗時にCloudFormationスタックをロールバックしないかn
BffFunction has no authentication. Is this okay?API Gatewayに認証をつけなくてよいかy
SAM configuration file [samconfig.toml]:設定を保存するファイル名Enter
SAM configuration environment [default]:設定を保存する環境名(プロファイルのようなもの)Enter
Save arguments to configuration file? [Y/n]:入力した設定を samconfig.toml に保存して次回以降使うか
Deploy this changeset? [y/N]:AWSにデプロイしてもいいかy

3.AWSにサインインし、CloudFormationを確認します。デプロイされていました

動作確認

  1. `sam deployを実行した際に`curlで実行します。成功しました
bff-on-aws % curl https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/Prod/posts-with-users |jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3843  100  3843    0     0   5315      0 --:--:-- --:--:-- --:--:--  5315
[
  {
    "id": 1,
    "author": "Leanne Graham"
  },
  {
    "id": 2,
    "author": "Leanne Graham"
  },
  {
    "id": 3,
    "author": "Leanne Graham"
  },

・・・・・省略・・・・・ 

  {
    "id": 99,
    "author": "Clementina DuBuque"
  },
  {
    "id": 100,
    "author": "Clementina DuBuque"
  }
]
bff-on-aws % 

最後に

1. .gitignoreファイルを作成します(GitHubに登録したくないものを指定します)

# Node.js dependencies
node_modules/
package-lock.json
npm-debug.log*

# SAM build artifacts
.aws-sam/
.env
*.template.yaml  # ビルド後に生成される template

# VSCode
.vscode/

# macOS system files
.DS_Store

# Logs
logs/
*.log

# SAM config
samconfig.toml

2.ファイルの状態を確認します

bff-on-aws % tree -L 2           
.
├── README.md
├── samconfig.toml
├── src
│   ├── app.js
│   ├── node_modules
│   ├── package-lock.json
│   └── package.json
└── template.yml

3 directories, 6 files
bff-on-aws % 

3. コミットし、プッシュします

% git push origin main

BFF(Backend for Frontend)ってそもそも何ですか?

A. BFF はフロントエンドごとに専用のバックエンドを用意する設計パターンです。複数のバックエンドAPIを統合・整形して、UIに最適化されたレスポンスを提供する役割を持ちます。

API Gatewayだけじゃダメなんですか?

A. API Gateway はルーティングや認証に便利ですが、複数のAPIを統合して加工したり、UI向けに整形する処理は得意ではありません。
そういったロジックを API Gateway に押し込むと、可読性や保守性が悪化するため、BFFで切り出すのが有効です。

マイクロサービスと何が違うの?

A. マイクロサービスは「業務単位」で分割されたサービスですが、BFF は「UIごとの最適化」に焦点を当てたインターフェース層です。
実際には、複数のマイクロサービスの“つなぎ役”として BFF が立つことが多いです。

いつBFFを導入するべきですか?

A. 以下のようなケースで導入を検討すると効果的です:

  • フロントエンドから複数APIを直接呼んでいてつらい
  • APIのレスポンスを毎回フロント側で整形している
  • モバイルとWebで違うデータ構造が必要になってきた
  • バックエンドの責務が肥大化してきた

デメリットはありますか?

あります。たとえば:

  • サービス数が増えるため、運用・監視コストが増える
  • BFF自体が肥大化すると、フロントエンドモノリスになる危険も

→ 小さく分離し、ドメインごとに責務を明確に保つことが大切です。

API Gateway のステージ名が Prod になっているのはなぜですか?

A. AWS SAM では、明示的に指定しない限り StageName が自動的に Prod(Pが大文字)になります。
ステージ名を変更したい場合は、AWS::Serverless::Api をテンプレートで明示的に定義し、StageName を設定することでカスタマイズ可能です。

BFFを含むアーキテクチャパターンを体系的に学べるおすすめ書籍

この書籍では、BFFを含むモダンなアーキテクチャパターン(API Gateway、サービス分離、境界づけられたコンテキストなど)を体系的に解説しています。
特に以下のような方におすすめです:

  • マイクロサービスとBFFの関係をもっと理解したい
  • アーキテクチャ設計の「なぜそうするのか」を知りたい
  • フロントとバックエンドの責務分離をどう進めるべきか悩んでいる

実践的なシナリオや設計思想が詰まっており、アーキテクチャに関わるエンジニアにとって即戦力となる一冊です。

広告

リソース

Backends for Frontends パターン | Amazon Web Services
このブログでは、Backend for Frontend パターンを実装し、マイクロサービスがドメインの集約の Mutation に関するイベントを発生させたときにリアルタイムの視覚的な更新を提供することによって、ユーザーインターフェース(...
Backends for Frontends pattern - Azure Architecture Center
Explore the Backends for Frontends pattern, which creates separate backend services to be consumed by specific frontend ...
Sam Newman - Backends For Frontends
sam local start-api - AWS Serverless Application Model
コマンドラインインターフェイス (AWS SAMCLI) AWS Serverless Application Model sam local start-apiサブコマンドのオプション。

これまで、BFF(Backend for Frontend)の基本的な概念から、実際のAWS環境上での実装手順までを解説してきました。
特に、複数のバックエンドAPIを統合し、UIごとに最適化されたレスポンスを提供するという役割において、BFFの重要性は非常に高いと考えます。

本記事で紹介したような構成は、以下のような課題を抱える開発チームにとって、大きな効果をもたらすはずです:

  • フロントエンドが複数のAPIを直接呼び出しており、ネットワーク負荷やUIロジックの肥大化が課題になっている
  • バックエンドにあらゆるデータ整形処理が詰め込まれ、責務の分離が曖昧である
  • Web/モバイルといった異なるクライアントでの最適なレスポンス設計に悩んでいる

今後の活用アイデア

  • 認証付きBFF(JWT / Cognito連携):UIに応じた認可制御を実装
  • APIキャッシュ戦略の導入:BFFレイヤーにキャッシュを持たせることでレスポンス高速化
  • OpenAPIを活用した型安全な開発:フロントとの契約を明示し、開発効率を高める
  • GitHub ActionsなどによるCI/CDの自動化:デプロイの手間を最小化し、安心して更新できる環境を構築

コメント

タイトルとURLをコピーしました