Site icon imageTomoMemo.dev

Memo on programming for Junior SWE. Provided by Tomo with passion.

郵便番号・デジタルアドレスAPIを触ったのでまとめる

Icon in a callout block
この記事はG's ACADEMY【技術記事書いてみた編】 Advent Calendar 2025、12/11投稿分となります

G’s FUKUOKA Dev03期、現役のバックエンドエンジニア、そして2025年よりチューターとして関わらせていただくことになりました、自称筋肉担当です。

ようやくこのAPIを触れる機会ができたので、どんなもんかざっくりとまとめていきます。

  • リポジトリ

https://github.com/tomohiro-dev/research-postal-code-digital-address-api

概要

  • 日本郵政が提供する「郵便番号・デジタルアドレスAPI」の仕様理解が目的
  • Next.js(App Router)を用いた BFF(Backend for Frontend)アーキテクチャでの実装検証をしてみる

正直なところ、Next.jsをつかうまでもなかったですが、普段見える側の開発を全然していないのでいい機会でした。

ひとまず、local環境下でAPIを叩くこと、そして叩く画面は作れたのでよしとします。

検証環境とアーキテクチャ

技術スタック
  • Framework
    • Next.js (App Router)
  • Language
    • TypeScript
  • Styling
    • Tailwind CSS
  • Deployment Verification
    • Vercel(の予定だったがサーバーが必要なのでどうデプロイするかだけ知る目的で動かした→現在は削除済)

選定基準は、今回は検証目的のため「使いたい技術」を優先しました。

アーキテクチャ (BFFパターン)

CORS制限の回避およびAPIキー(Client Secret)の隠蔽のため、BFF (Backend for Frontend) パターンを採用しました。

構成イメージ: Client -> BFF (Next.js Route Handler) -> Japan Post API

最初の壁:謎の "400 Bad Request"

検証を開始してすぐ、公式(と思われる)エンドポイントに接続しても 400 Bad Request が返ってくる事象に直面しました。

調査プロセス

リファレンスと実際の挙動に乖離があり、以下の点を調査しました。

  • パラメータ名は正しいか? (client_secret vs secret_key)
  • 接続先URLは正しいか? (api.da.pf... vs stub-qz73x...)
判明した事実

(結論、早く仕様書を見ておけばよかった、という話)

検証および公式Mock仕様書の確認の結果、以下の仕様が判明しました。

環境によるパラメータ名の違い

  • 本番環境 (推定): OAuth標準の client_secret
  • Mock環境 (仕様書準拠): secret_key ※ Mock環境では、リクエストパラメータとして secret_key が必須であり、標準的な client_secret では動作しません。

エンドポイントの使い分け

  • 本番環境: https://api.da.pf.japanpost.jp/api/v1
  • Mock環境 (Stub): https://stub-qz73x.da.pf.japanpost.jp/api/v1

また、レスポンスのトークンキーも access_token ではなく token が返却される点についても、Mock仕様書通りの挙動であることが確認できました。

環境差異を吸収するAPIクライアント

JapanPostClient クラスの設計

環境変数(例: USE_MOCK_ENV)により、接続先と認証パラメータを動的に切り替えるロジックをBFF層に持たせることで、フロントエンド側は統一された型(Interface)でデータを扱えるようにしました。

interface JapanPostSearchResponse {
  page: number;
  limit: number;
  count: number;
  searchtype: string;
  addresses: JapanPostAddress[];
}

IPアドレス制限 vs IP偽装

BFFを構築し、ローカル環境(Mock)での動作確認は完了しましたが、Vercelへのデプロイ時に新たな壁「IPアドレス制限」に阻まれました。

仮説と検証

「Vercelからのリクエストでも、X-Forwarded-For ヘッダーで許可されたIPを偽装すれば通るのではないか?」という仮説(Qiita記事などを参考)を立て、検証を行いました。

結果は400 Bad Request

検証の結果、IP偽装は失敗しました。 日本郵政のAPIサーバー側で、接続元の実IPアドレスを厳格に検証しているようです。

結論

VercelやAWS Lambdaなどのサーバーレス環境(IPアドレスが動的に変化する環境)から本番APIを利用する場合、以下が必須となります。

  • 固定IPを持つホストの利用
    • EC2やVPS等の固定IPサーバーからアクセスする

[余談]DynamoDBへの応用

このAPI仕様をもとに、仮にDynamo DBでこのAPIを作るためのスキーマ設計案を検討。

  • Access Patterns: 郵便番号またはデジタルアドレスからの住所取得
  • PK: zip_code or dgacode
  • SK: address or id

そもそも、このAPIを使えばいい話なので、実務で使うために作るよりも、学習のために作ることを優先した上でのアイディアです。

Powered by Tomo with passion.