← トップへ

家計の記録 Web API

金額と店名を送ると分類ルールで自動分類し、月ごと・分類ごとに集計する Web API。C# / ASP.NET Core で作り、Azure に公開している。

作成中 期間: 2026-10〜

  • C#
  • ASP.NET Core
  • Entity Framework Core
  • PostgreSQL
  • Docker
  • Azure Container Apps
  • GitHub Actions
家計の記録 Web API の流れの図。取引を登録し、分類ルールで自動分類し、月ごと・分類ごとに集計する。Docker のコンテナとして Azure Container Apps で動いている。

AI との分担

自分でやったこと: 設計の決定(エラーの返し方、層の分け方、テーブル、Azure の載せ先)と、Azure への公開操作は自分で行った。コードも、分類の API は自分で書き、取引・自動分類・集計などは重要な部分(検索条件、所有者の確認、更新と削除の判断、自動分類の判定など)を自分で書いた。

AI に任せた・手伝ってもらったこと: 主な使い方は、設計の壁打ち、コードのレビュー、「今の実装に穴がないか」の確認。提案を採用するかは自分で決めた。一部は AI に任せた(穴埋め用のひな形とヒントの作成、DB を使う統合テストと GitHub Actions の設定ファイル、README の文章)。

困りごと

家計簿アプリに、支払いのたびに金額と店名をスマホで入力するのが面倒でした。自動で入力されてほしい一方、現金払いのために、手で入力することもできるようにしたいと考えました。家計簿アプリはすでにありますが、見やすさや調整のしやすさを自分で決めたいと思い、自分で作ることにしました。

作ったもの

金額と店名を送ると、分類ルールで自動的に分類して記録する Web API です。

まだできていないのは、ログインです。次に作る予定です。

設計で決めたこと

エラーの返し方を、作り始める前に決めた。 形は Problem Details という決まった JSON にそろえ、中に「category.duplicate_name」のような文字列のエラーコードを入れました。入力が正しくないときは 400、見つからないときは 404、今あるデータとぶつかるときは 409 と使い分けています。エラーコードを数字ではなく文字列にしたのは、読んで意味が分かるからです。

処理を、コントローラー・サービス・DB の読み書きの3つに分けた。 コントローラーは受け取って結果を返すだけにして、決まりごとの処理はサービスに置いています。サービスは DI で渡すので、テストで差し替えられます。

分類の名前の重複は、同じ人の中だけで禁止した。 ユーザー ID と名前の組に、DB の一意制約を付けています。別の人なら同じ名前でよいという決めです。

DB は PostgreSQL にした。 Azure SQL だと Azure に縛られそうで、PostgreSQL なら Azure 以外でも使えるからです。

Azure の載せ先は Container Apps にした。 手元で作った Docker のイメージを、そのまま本番で動かせるからです。

苦労したこと

EF Core の関数を知らないこと。 私が関わってきたゲーム開発では、プレイ中の処理で LINQ を使うと GC(メモリの自動解放)が起きて、カクつきの原因になるため、毎回 for 文で書いて負荷を抑えていました。LINQ の仕組みはある程度分かっていましたが、EF Core が用意している、LINQ に似た DB 用の関数は、「どんな関数があり、それぞれが何をするのか」が分からず、そこで時間がかかりました。

URL とエラーコードの設計。 DI は、開発リードのときに技術選定で VContainer を入れて使っていたので、考え方はある程度分かっていました。一方、API では「URL にどの情報を入れるか」と「エラーをどう返すか」を決めた経験がなく、ここで一番苦戦しました。エラーは Problem Details の形にそろえ、400・404・409 を使い分ける形に決めました。

まだ理解の途中のこと。 Azure は、まだ十分に理解できておらず、勉強中です。GitHub Actions は、何をしているかは分かります。仕事では GitLab と Jenkins で CI/CD を実装しているので、仕組みの考え方は同じだと思っています。ログインはこれからです。公式は、自前の JWT 発行をテスト目的以外では勧めていませんが、自主学習も兼ねて JWT で作るつもりで、公式の注意を調べてから入れる予定です。