Zum Hauptinhalt springen
••
Sicherheitslücken (CVE)IT Security News Roundup: 2026-10-05(05.10.2026 um 23:56 Uhr)
•
Sicherheitslücken (CVE)IT Security News Hourly Summary 2026-10-06 00h : 4 posts(06.10.2026 um 00:00 Uhr)
•
IT Security NachrichtenAWS Continuum sets a new standard in autonomous code security(06.10.2026 um 00:01 Uhr)
•••
IT Security NachrichtenAmazon Prime Deal Days: Technik-Blitzangebote im Überblick 05. Oktober(05.10.2026 um 07:11 Uhr)
•
IT Security NachrichtenPrime Day 2026: Die besten Deals auf Amazon im Überblick(06.10.2026 um 00:00 Uhr)
••••
Sicherheitslücken (CVE)IT Security News Roundup: 2026-10-05(05.10.2026 um 23:56 Uhr)
•
Sicherheitslücken (CVE)IT Security News Hourly Summary 2026-10-06 00h : 4 posts(06.10.2026 um 00:00 Uhr)
•
IT Security NachrichtenAWS Continuum sets a new standard in autonomous code security(06.10.2026 um 00:01 Uhr)
•••
IT Security NachrichtenAmazon Prime Deal Days: Technik-Blitzangebote im Überblick 05. Oktober(05.10.2026 um 07:11 Uhr)
•
IT Security NachrichtenPrime Day 2026: Die besten Deals auf Amazon im Überblick(06.10.2026 um 00:00 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

R2E APIのデモUIを作りました!Next.js + Render でバックエンド連携する実装記

はじめに 以前 Research→Experience API を作りました という記事で、FastAPI + PostgreSQL(pgvector) で「ビジネス課題 → 関連論文探索 → 示唆」を返す API を紹介しました。 今回は、この API を体験できるフロントエンド UI を Next.js(Verce…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!




はじめに



以前 Research→Experience API を作りました という記事で、FastAPI + PostgreSQL(pgvector) で「ビジネス課題 → 関連論文探索 → 示唆」を返す API を紹介しました。



今回は、この API を体験できるフロントエンド UI を Next.js(Vercel)ブログの /portfolio/r2e に追加した実装記です。バックエンドは Render の無料枠で動かしています。






完成したもの





  • URL: /portfolio/r2e


  • 機能: 3タブUI(Search / Sources / Status)


  • バックエンド: Render(https://research-to-experience-api.onrender.com)


  • フロントエンド: Next.js(Vercel)



Search タブでビジネス課題を入力すると、Sources タブに論文リストが表示されます。






アーキテクチャ設計






要件




  1. フロントエンドからバックエンド API を叩く

  2. 本番環境では Render、開発環境では localhost:8000 を使い分け

  3. CORS を避けたい(同一オリジン扱いにしたい)






選択肢



最初は Next.js の rewrites を使うことを考えましたが、Vercel 上で POST リクエストが正しくプロキシされない問題が発生しました。最終的に Next.js API Route でバックエンドにプロキシする方式にしました。




// src/app/api/r2e/[...path]/route.ts
export async function GET(request: NextRequest, { params }: { params: { path: string[] } }) {
return proxyRequest(request, params.path, 'GET')
}

export async function POST(request: NextRequest, { params }: { params: { path: string[] } }) {
return proxyRequest(request, params.path, 'POST')
}









ディレクトリ構成






external/research-to-experience-api/
├── client.ts # APIクライアント(search, health)
└── README.md # 使い方

src/app/
├── api/r2e/[...path]/
│ └── route.ts # バックエンドプロキシ
└── portfolio/r2e/
└── page.tsx # メインUI









実装詳細






1. API クライアント(薄いラッパー)



external/ フォルダに API クライアントを配置。ドメイン非依存の相対パスで実装しています。




export type SearchResponse = {
summary?: string[]
business_implications?: string[]
sources?: Source[]
}

export async function search(query: string): Promise<SearchResponse> {
const r = await fetch('/api/r2e/search', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ query }),
})
if (!r.ok) {
const errorData = await r.json().catch(() => ({}))
if (r.status === 504) {
throw new Error('バックエンドAPIのコールドスタート中です。30秒ほど待ってから再度お試しください。')
}
throw new Error(errorData.details || `HTTP ${r.status}`)
}
return r.json()
}









2. API Route(プロキシ実装)



Next.js API Route でバックエンド API にプロキシします。環境変数 BACKEND_URL で開発/本番を切り替えます。




const BACKEND_URL = process.env.BACKEND_URL || 'https://research-to-experience-api.onrender.com'

async function proxyRequest(
request: NextRequest,
pathSegments: string[],
method: 'GET' | 'POST'
) {
const path = pathSegments.join('/')
const url = `${BACKEND_URL}/${path}`

const options: RequestInit = { method, headers: { 'Content-Type': 'application/json' } }

if (method === 'POST') {
const body = await request.text()
options.body = body
}

// タイムアウト設定(Render のコールドスタート対応)
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 90000)

try {
const response = await fetch(url, { ...options, signal: controller.signal })
clearTimeout(timeoutId)
const data = await response.text()
const jsonData = JSON.parse(data)
return NextResponse.json(jsonData, { status: response.status })
} catch (fetchError) {
clearTimeout(timeoutId)
if (fetchError instanceof Error && fetchError.name === 'AbortError') {
return NextResponse.json(
{ error: 'Request timeout', details: 'Backend API did not respond within 90 seconds...' },
{ status: 504 }
)
}
throw fetchError
}
}









3. メインUI(3タブ構成)



React の state でタブ管理、API クライアントでデータ取得します。




export default function R2EPage() {
const [tab, setTab] = useState<Tab>('Search')
const [query, setQuery] = useState('')
const [loading, setLoading] = useState(false)
const [resp, setResp] = useState<SearchResponse | null>(null)

const doSearch = async () => {
setLoading(true)
setError(null)
try {
const data = await doApiSearch(query)
setResp(data)
setTab('Sources') // 成功時はSourcesへ切替
} catch (e: unknown) {
const message = e instanceof Error ? e.message : 'request failed'
setError(message)
} finally {
setLoading(false)
}
}

// ... UI実装
}






タブ構成:





  • Search: ビジネス課題を入力、検索実行


  • Sources: 検索結果の論文リスト(Title, URL, Confidence)


  • Status: /health エンドポイントの疎通確認






環境設定






Vercel 環境変数



Vercel CLI で環境変数を設定しました。




# Production / Preview
echo -n "https://research-to-experience-api.onrender.com" | vercel env add BACKEND_URL production
echo -n "https://research-to-experience-api.onrender.com" | vercel env add BACKEND_URL preview

# Development(ローカル開発用)
echo -n "http://localhost:8000" | vercel env add BACKEND_URL development









Render デプロイ



バックエンドは Render の無料枠でデプロイ。Dockerfile を使っています。





  • URL: https://research-to-experience-api.onrender.com


  • Health Check Path: /health


  • Auto-Deploy: Yes






ハマりポイントと対応






1. POST リクエストが 405 エラー



問題: Next.js の rewrites を使ったが、Vercel 上で POST が正しくプロキシされなかった。



対応: rewrites をやめ、Next.js API Route でプロキシする方式に変更。




// ✗ 最初の実装(rewrites)
// next.config.mjs
async rewrites() {
return [{ source: '/r2e/:path*', destination: `${BACKEND_URL}/:path*` }]
}

// ✓ 最終実装(API Route)
// src/app/api/r2e/[...path]/route.ts
export async function POST(...) { return proxyRequest(...) }









2. Render のコールドスタート



問題: Render 無料枠は15分間アクセスがないとスリープし、初回アクセスで30〜60秒かかることがある。



対応:




  • タイムアウトを90秒に延長

  • 504エラー時に「コールドスタート中です。30秒ほど待ってから再度お試しください。」と案内




if (r.status === 504) {
throw new Error('バックエンドAPIのコールドスタート中です。30秒ほど待ってから再度お試しください。')
}









3. ビルド時の環境変数エラー



問題: Vercel ビルド時に BACKEND_URL が undefined になり、rewrites の destination が undefined/:path* になってエラー。



対応: API Route ではランタイムで process.env.BACKEND_URL を参照するため、ビルド時の問題は発生しない(rewrites から API Route に変更したので解決)。






学んだこと




  1. Next.js の rewrites は GET には向くが、POST は API Route が確実

  2. 無料ホスティング(Render)のコールドスタートを考慮した UX 設計が重要

  3. 環境変数はビルド時とランタイムで扱いが異なる






まとめ




  • Next.js API Route でバックエンドプロキシを実装

  • 3タブUIで R2E API を体験できるUIを追加

  • Render のコールドスタートに対応

  • Vercel 環境変数で開発/本番を切り替え



実際に /portfolio/r2e にアクセスして、ビジネス課題から論文探索までの体験を試してみてください!






参考リンク



Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten R2E APIのデモUIを作りました!Next.js + Render でバックエンド連携する実装記

Thematisch verwandte Begriffe: APIのデモUIを作りましたNextjs, Render, でバックエンド連携する実装記 · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
Nächster Beitrag