mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-17 18:35:19 +02:00
feat: implement dynamic API proxying to FastAPI backend
- Added a new route handler for dynamic API requests, allowing proxying to the FastAPI backend. - Removed the previous rewrite configuration in next.config.ts for cleaner integration. - Updated .env.example to clarify backend URL usage.
This commit is contained in:
parent
e86d279d55
commit
9ecccc5403
3 changed files with 65 additions and 16 deletions
|
|
@ -1,7 +1,6 @@
|
|||
NEXT_PUBLIC_FASTAPI_BACKEND_URL=http://localhost:8000
|
||||
|
||||
# Server-only. Internal backend URL used by Next.js server code.
|
||||
# Falls back to NEXT_PUBLIC_FASTAPI_BACKEND_URL when unset.
|
||||
FASTAPI_BACKEND_INTERNAL_URL=https://your-internal-backend.example.com
|
||||
|
||||
NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=LOCAL or GOOGLE
|
||||
|
|
|
|||
65
surfsense_web/app/api/v1/[...path]/route.ts
Normal file
65
surfsense_web/app/api/v1/[...path]/route.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import type { NextRequest } from "next/server";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const HOP_BY_HOP_HEADERS = new Set([
|
||||
"connection",
|
||||
"keep-alive",
|
||||
"proxy-authenticate",
|
||||
"proxy-authorization",
|
||||
"te",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
]);
|
||||
|
||||
function getBackendBaseUrl() {
|
||||
const base = process.env.FASTAPI_BACKEND_INTERNAL_URL || "http://localhost:8000";
|
||||
return base.endsWith("/") ? base.slice(0, -1) : base;
|
||||
}
|
||||
|
||||
function toUpstreamHeaders(headers: Headers) {
|
||||
const nextHeaders = new Headers(headers);
|
||||
nextHeaders.delete("host");
|
||||
nextHeaders.delete("content-length");
|
||||
return nextHeaders;
|
||||
}
|
||||
|
||||
function toClientHeaders(headers: Headers) {
|
||||
const nextHeaders = new Headers(headers);
|
||||
for (const header of HOP_BY_HOP_HEADERS) {
|
||||
nextHeaders.delete(header);
|
||||
}
|
||||
return nextHeaders;
|
||||
}
|
||||
|
||||
async function proxy(
|
||||
request: NextRequest,
|
||||
context: { params: Promise<{ path?: string[] }> }
|
||||
) {
|
||||
const params = await context.params;
|
||||
const path = params.path?.join("/") || "";
|
||||
const upstreamUrl = new URL(`${getBackendBaseUrl()}/api/v1/${path}`);
|
||||
upstreamUrl.search = request.nextUrl.search;
|
||||
|
||||
const hasBody = request.method !== "GET" && request.method !== "HEAD";
|
||||
|
||||
const response = await fetch(upstreamUrl, {
|
||||
method: request.method,
|
||||
headers: toUpstreamHeaders(request.headers),
|
||||
body: hasBody ? request.body : undefined,
|
||||
// `duplex: "half"` is required by the Fetch spec when streaming a
|
||||
// ReadableStream as the request body. Avoids buffering uploads in heap.
|
||||
// @ts-expect-error - `duplex` is not yet in lib.dom RequestInit types.
|
||||
duplex: hasBody ? "half" : undefined,
|
||||
redirect: "manual",
|
||||
});
|
||||
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: toClientHeaders(response.headers),
|
||||
});
|
||||
}
|
||||
|
||||
export { proxy as GET, proxy as POST, proxy as PUT, proxy as PATCH, proxy as DELETE, proxy as OPTIONS, proxy as HEAD };
|
||||
|
|
@ -44,21 +44,6 @@ const nextConfig: NextConfig = {
|
|||
},
|
||||
},
|
||||
|
||||
// Proxy /api/v1/* to the FastAPI backend. Keeps the real backend host
|
||||
// out of the client bundle. FASTAPI_BACKEND_INTERNAL_URL is server-only.
|
||||
async rewrites() {
|
||||
const target =
|
||||
process.env.FASTAPI_BACKEND_INTERNAL_URL ||
|
||||
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL ||
|
||||
"http://localhost:8000";
|
||||
return [
|
||||
{
|
||||
source: "/api/v1/:path*",
|
||||
destination: `${target.replace(/\/+$/, "")}/api/v1/:path*`,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
// Configure webpack (SVGR)
|
||||
webpack: (config) => {
|
||||
// SVGR: import *.svg as React components
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue