はじめに
バックエンドエンジニアとして3年ほどの経験を積んできました。
最近では、AIを日々の開発にフル活用してコーディングのスピードを上げる試みを続けています。
AI時代になり、動くものを作るハードルはかつてないほど下がりました。だからこそ、今改めて自分のエンジニアとしての信条を言語化しておきたいと考え、この記事を書きました。
経験のある先輩方には当たり前の内容かもしれませんが、実務での失敗や学びを経てたどり着いた、私なりのバックエンドエンジニアとしての大切にしていることです。
1 プロダクトが苦しくなる理由は、機能不足より運用設計不足であることが多い
新機能の開発は目に見えやすく、評価もされやすいです。一方で、非機能要件や運用・保守の設計は、リリース前には価値が見えにくいため、後回しにされがちです。
でも実際には、プロダクトの継続性を左右するのはむしろこちらです。たとえば、以下のような状態は珍しくありません。
-
監視設計が弱く、障害の初動が遅れる
-
ログが不十分で、原因調査に時間がかかる
-
リトライやタイムアウト設計が甘く、一部障害が全体障害に波及する
-
利用者増加時の負荷を見越せておらず、DBや外部API連携が詰まる
-
コスト試算が曖昧で、伸びるほど利益を圧迫する構造になる
つまりバックエンド開発では、作れるかだけでなく、安全に動かし続けられるかまで考えて初めて設計が完了するのだと思います。
2 コスト意識も技術力の一部である
「開発は完了したが、月々いくらかかるのか明確でない」
これは技術的負債であると同時に、事業上のリスクでもあります。
特にバックエンドでは、アーキテクチャやデータ設計、インフラ構成の選択が、そのままランニングコストに跳ね返ります。もちろん、ビジネス判断として一時的にコストをかけてでもスピードを優先する場面はあります。
ただ、その判断をするにしても、何にどれだけかかるのか、なぜ今その選択をするのかが見えていることが重要です。堅牢さを保ちながら、最適なコストで運用し続けること。これは単なる節約ではなく、持続可能なシステムを設計する技術力そのものだと思います。
3 非機能要件を担保する、価値あるテスト設計
ここで、最近個人的に刺さった記事をご紹介します。Qiitaで大きな話題になっていた、歴20年の大先輩による記事です。
AIに意味のあるテストを書かせるには、観点を指示しろ
AIは「テストを書いて」と言えば、とりあえず生成する。だがハッピーパス(正常系)しか書かない、あるいは網羅的なテストを書かせようとするとモックを多用して意味のないテストをすることがある。意味のあるテストにするには、丸なげするよりは、ステップを分けて確認した方がよい。
--- エンジニア歴20年の私が、素人バイブコーディング勢に物申す より引用
この言葉は、まさに私が実務の中で強く学んだことそのものでした。
以前、私はテストケースを作るときに「正常系」「異常系」「セキュリティ」などの観点を列挙して、ある程度整理できた気になっていました。でも実際にレビューを受けたとき、全然網羅されていないと指摘いただいたのです。
そこで理解したのは、本当の網羅性は、単に項目を並べることではなく、観点を掛け合わせること(マトリックス) で生まれるということでした。
AIへの丸投げ
「異常系のケースを出して」→ AIは「入力値が空の場合」などを出す
人間による観点指示
「インフラの瞬断とDB書き込み中のリトライが重なった時のデータ整合性を疑って」→ AIは初めて意味のある、急所を突いたテストを生成する
AIに大量のケース案を出させる力はあっても、どの観点でシステムを疑うべきかという知略を授けるのは人間にしかできない設計行為なのだと痛感しました。
4 セキュリティも実装ではなく観点で差がつく時代
セキュリティについて意識できるジュニアエンジニアは、希少な存在だと言われることがあります。 多くの場合は「機能が動くこと」で手一杯になりがちですが、バックエンドを担う以上、セキュリティは不可欠な要素だと考えています。
これまでのセキュリティ対策は、既知の脆弱性パターンとコードを照合するパターンマッチングが主流でした。しかし、最近のAI技術の進化はその前提を大きく変えようとしています。
例えば、Anthropicが発表したClaude Code Securityのような自律型ツールは、コードのコンポーネント間の相互作用やデータの流れを意味的に理解し、ビジネスロジックの欠陥まで特定できるといいます。内部テストでは、専門家の手動解析を数十年にわたってすり抜けてきた未知の脆弱性を500件以上も発見したという報告もあり、もはや人間が一つずつ脆弱性パターンを暗記してコードを書く時代は終わりを告げようとしています。
AI時代にエンジニアが担うセキュリティ
こうした高度なセキュリティツールが登場する中で、私たちエンジニアの役割はどこにあるのでしょうか。私は以下の2点に集約されると考えています。
- 守るべき定義
AIはコードの不備を見つけることは得意ですが、このプロダクトにおいて、どのデータが最も重要で、どのビジネスロジックに特権的な保護が必要か という優先順位の判断は、ドメイン知識を持つ人間にしかできません。
- 多段階の検証
最新のAIツールは自己検証プロセスを経て修正案を提示しますが、最終的なパッチの適用には人間の承認 を必要とする設計になっています。これは、セキュリティ上の修正がシステムのパフォーマンスや他機能への副作用を及ぼさないか、運用全体を俯瞰して判断する責任を人間が負っているからです。
こうした2点を常に意識できていれば、例えセキュリティに対しての深い知識がまだ十分でなかったとしても、AIと協力して急所を突いた安全な設計を行うことができるのだと思います。
お客様のプロダクトをどう守るか
こうした最新ツールの導入検討や、セキュリティルールの策定も、案件における重要な設計の一部です。
お客様の大切なプロダクトを預かる身として、どのフェーズで、どのツールを、どういう基準で運用するか を考えることは、重要なことだと考えています。
5 スケールアップは根本的な解決ではないことがある
負荷が高まったとき、まずサーバーのスペックを上げる。これは現実的で、時には正しい判断です。ただ、それ「だけ」に頼り続けると、根本原因を見失います。
本当に見るべきなのは、何が起きているかを見えるようにすること(可観測性) です。
どこがボトルネックになり、どの処理が遅延を生んでいるのか。これらがログやメトリクスで揃っていて、チーム全員が追える状態にあるからこそ、急なトラブルにも落ち着いて向き合えます。
また、API仕様をOpenAPI(Swagger) などで明文化しておくことも重要だと考えています。
【実践編】DBスパイクの原因究明とパラメーターチューニング
実際のプロジェクトで「特定の条件下でDBのCPU使用率が100%に張り付く」という課題に直面しました。この時、私がチームメンバーと共に取り組んだアプローチは、まさに観点を持って設計することの連続でした。
-
推測ではなく観測から始める
まず、闇雲にインスタンスサイズを上げるのではなく、Datadog APMを活用してボトルネックを可視化しました。どのAPIが実行された時に、DBの負荷が上がっているのか を、トレース情報とDBメトリクスを相関させて特定。そこから、特定の業務ロジックに伴うクエリの波が見えてきました。 -
SQLの改善
原因となったAPIに対し、実行計画の最適化を行いました。複雑なサブクエリを整理し、JOINへ書き換えたり、インデックスを無効化してしまう暗黙的な型変換を排除して厳密な比較演算子へ修正したりと、地道な改善を繰り返しました。 -
あえてオートスケールを止めるというテスト設計
DBの限界性能を見極めるため、負荷試験ではあえてスケールアウトを無効化して実施しました。バッファサイズ等のパラメーターを細かくチューニングし、その環境にJMeterで高負荷をかけ、インフラの力技ではなく、設定とロジックでどこまでスループットが向上するか を定量的に計測しました。
この経験を通じて、非機能要件の重要性を実感しました。
6 壊れないことより、壊れたときにすぐ気づけることが強い
現実のシステムにおいて絶対に壊れないを目指し切るのは難しいです。だからこそ重要なのは、壊れたときにすぐに気づけること、そして原因を早く特定できることです。
- 異常を監視で即検知できるか
- ログから原因にたどり着けるか
- 障害時の一次対応手順が明確か
保守性が高いシステムとは、単にコードがきれいなシステムではなく、問題が起きたときにチームが迷わず対処できるシステムだと考えています。数ヶ月後の自分や、これから参加するチームメンバーに負債を残さないためにも、運用手順や仕様はできる限り言語化・可視化しておくべきだと思います。
7 AI時代にエンジニアの価値になるのは、「観点を持って設計する力」
AIがコードを書ける時代、エンジニアの価値は書くことから観点を見抜き、全体を設計することへ移っていると感じています。
こうした設計の観点を養う上で、私にとってバイブルとなっている本があります。
もしこれから設計を深く学びたいという方がいれば、以下の順に読み進めるのがおすすめです。
①『良いコード悪いコードで学ぶ設計入門』
まずは保守性の高いコードとは何かという、エンジニアの基礎体力を養えます。
②『現場で役立つシステム設計の原則』
コードの先にある、ビジネスロジックと設計をどう結びつけるかの視座が手に入ります。
③『システム設計の面接試験』
タイトルや本のコンセプトからシステムデザイン試験対策かと思いきや、実は大規模トラフィックや負荷分散など、バックエンドとしての戦い方の総仕上げになる本質的な内容が詰まっています。
これらの本からは、変更に強いコードの書き方だけでなく、システムが直面する荒波にどう立ち向かうかという本質を学びました。内容を暗記するほどこれからも読み込みたいと考えています。
機能開発はもちろん大事です。でもその機能を、安心して、長く、価値ある形で届け続ける。その土台を作ることこそ、バックエンドエンジニアの専門性であり、一番大切にしていることです。
8 リリース前に最低限確認したいこと
最後に、自分への戒めも込めて、最低限確認したい観点をまとめます。
リリース前チェックリスト
-
負荷の見積もり
- 想定トラフィックに対する負荷の見積もりはできているか
-
ボトルネック把握
- ボトルネックになりうるDBアクセスや外部API呼び出しを把握しているか
-
セキュリティ
- 既知のパターンだけでなく、ビジネスロジックの不備を自ら疑えているか
-
可観測性
- 障害時に追跡できるログ、メトリクス、アラートが揃っているか
-
API仕様
- OpenAPI(Swagger)などでAPI仕様が明文化されているか
-
耐障害性
- タイムアウト、リトライ、冪等性の設計がされているか
-
初動対応
- 障害時の一次対応手順や切り戻し方法が整理されているか
-
コスト試算
- ランニングコストの概算が把握できているか
-
テスト網羅性
- セキュリティ、異常系、インフラ障害を掛け合わせたテスト観点が洗い出せているか
機能を作ることと、作ったものを生かし続けること。
この2つを切り離さずに考えられるエンジニアでありたいです。
参考記事・書籍
【記事】
エンジニア歴20年の私が、素人バイブコーディング勢に物申す
Anthropicが自律的AI脆弱性検出ツール「Claude Code Security」をリリース
【書籍】
良いコード悪いコードで学ぶ設計入門
現場で役立つシステム設計の原則
システム設計の面接試験