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_secretvssecret_key) - 接続先URLは正しいか? (
api.da.pf...vsstub-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_codeordgacode - SK:
addressorid
そもそも、このAPIを使えばいい話なので、実務で使うために作るよりも、学習のために作ることを優先した上でのアイディアです。
TomoMemo.dev