2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「全部 Next.js に入れたい」から始まった時間のかかる非同期処理の話

2
Posted at

はじめに

Next.js は、フロントエンドとバックエンドを一つのプロジェクトで管理できる非常に便利なフレームワークです。

一方で、多くの開発者が一度は直面する問題があります。

それが、「長時間実行される非同期タスクをどう扱うか」 という問題です。

画像処理、大規模なデータ分析、あるいは AI ワークフローなど、
完了までに 10分〜30分かかる処理が必要になると、

「フロントエンドは Next.js、
バックエンドは Go や別 Worker に分けるしかない」

となりませんか?

今回は、投稿者の許可を得たうえで、
Reddit に投稿されていた

できる限り Next.js のコードベースを維持しながら、
長時間タスクを安全に扱う

という実践的なアプローチをご紹介します。

1.アーキテクチャの方針

  • フロントエンドとバックエンドを一つの Next.js + TypeScript プロジェクトに統合する(長時間タスクのためだけにGoなどの別サービスを追加管理したくない)
  • 基本方針:遅くても構わない、クラッシュだけは絶対にダメ

2.APIレイヤー

  • API は、request を受信すると、即座にデータベースへPENDING状態のtaskを作成
  • taskId をすぐに返し、リクエストをブロックしない
    image.png

3.フロントエンドのポーリング

  • フロントエンドが taskId を受け取った後、定期的にAPIをポーリングしてタスクの状態を確認する
  • WebSocket は採用しない——30分単位の長時間タスクにはポーリングで十分なため

4.バックグラウンドワーカー(ここが重要!)

  • プロジェクトのルートディレクトリに scripts/ ディレクトリを作成し、各タスクに対応する独立したファイルを配置する
  • すべてのワーカーは統一されたパイプラインに従って動作する:
    1. データベースを継続的にポーリングし、PENDING 状態のタスクを検索する
    2. lockedBy + lockedAt フィールドを使ってタスクをロックする(複数ワーカーによる二重処理を防止)
    3. 実際の workflow を実行する
    4. タスクの状態を COMPLETED(または失敗状態)に更新する

5.デプロイ方法

  • ワーカーサービスは Next.js アプリケーションとは 独立して別々に起動する
  • Kubernetes Jobs を使ってワーカーをデプロイし、同時実行数を細かく制御できる

6.実際に感じたメリット

  • 同一の TypeScript コードベース(型定義・ユーティリティ関数・データベースモデル)を共有できる
  • ワーカーが独立して動作するため、Next.js メインアプリケーションの安定性に影響しない
  • 同時実行数が制御可能で、リソースの分離が明確

この構成を「再利用可能」にしたかった

投稿者はその後、この構成を reusable template 化したいと考え、
Claude Code に対して以下の prompt を渡して試したそうです。

Create a Next.js fullstack system for handling long-running async tasks: API routes immediately return taskId after creating PENDING tasks in database, frontend polls for status, background workers in scripts/ directory poll database for tasks using locking mechanism (lockedBy/lockedAt fields), execute workflows (deploy workers as Kubernetes Jobs), and update status to COMPLETED. Use Prisma, TypeScript

ただ、結果はそこまで理想的ではなかったそうです。

特に難しかったのは、

  • Worker を Next.js runtime から分離して動かすこと
  • lockedBy / lockedAt を使った lock mechanism
  • 「コードベースは統一するが、実行環境は分離する」という設計意図

などのニュアンスを、自然言語だけで正確に伝える部分でした。

その後 Verdent を試したところ、
こうした architecture の意図やworkflow 全体の構成が、より自然に整理・生成できたとのことです。

image.png

投稿者は当初、
この構成を OSS template として公開しようと考えていたそうです。

しかし最終的には、

「template を配布するより、
prompt を共有する方が面白いのではないか」

という考えに変わったとのこと。

boilerplate code を毎回書くよりも、

「どういうシステムを作りたいか」

を自然言語で定義していく方が、
これからの開発スタイルに近いのかもしれません。

おわりに

今回紹介した構成で印象的だったのは、
単なる「Next.js の worker 構成」ではなく、

「コードを書く」より先に、
「どういうシステムとして動かしたいか」を自然言語で定義している

という点でした。

最近は AI coding の進化によって、実装そのものよりも、

  • architecture の意図
  • workflow の流れ
  • system 全体の責務分離

をどう言語化するかが、より重要になってきている気がします。

もし、

  • 「全部を別 service に分けたくない」
  • 「TypeScript codebase を維持したい」
  • 「AI と一緒に architecture を整理したい」

と感じている方は、一度 Verdent を試してみると面白いかもしれません。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?