Skip to content

Instantly share code, notes, and snippets.

@jasonblanchard
Last active March 29, 2023 16:21
Show Gist options
  • Save jasonblanchard/a5f7ebe92ee0b235dabe42232acda5a7 to your computer and use it in GitHub Desktop.
Save jasonblanchard/a5f7ebe92ee0b235dabe42232acda5a7 to your computer and use it in GitHub Desktop.
buf connect with next 13 route handlers
import {
ConnectRouter,
ConnectRouterOptions,
createConnectRouter,
} from "@bufbuild/connect";
import type { UniversalHandler } from "@bufbuild/connect/protocol";
import { createFetchHandler, FetchHandler } from "./fetch-universal-handler"; // https://gist.github.com/timostamm/5ca423155a0ddf03678ddc61f08cf4bd
interface NextJs13ApiRouterOptions extends ConnectRouterOptions {
/**
* Route definitions. We recommend the following pattern:
*
* Create a file `connect.ts` with a default export such as this:
*
* ```ts
* import {ConnectRouter} from "@bufbuild/connect";
*
* export default (router: ConnectRouter) => {
* router.service(ElizaService, {});
* }
* ```
*
* Then pass this function here.
*/
routes: (router: ConnectRouter) => void;
prefix?: string;
}
type NextApiRouteHandler = (req: Request) => Promise<Response>;
interface ApiRoute {
POST: FetchHandler | NextApiRouteHandler;
}
export function next13JsApiRouter(options: NextJs13ApiRouterOptions): ApiRoute {
const router = createConnectRouter(options);
options.routes(router);
const prefix = options.prefix ?? "/api";
const paths = new Map<string, UniversalHandler>();
for (const uHandler of router.handlers) {
paths.set(prefix + uHandler.requestPath, uHandler);
}
async function POST(req: Request) {
const requestPath = new URL(req.url).pathname;
const uHandler = paths.get(requestPath);
if (!uHandler) {
return new Response(null, { status: 404 });
}
const fetchHandler = createFetchHandler(uHandler);
return await fetchHandler(req);
}
return {
POST,
};
}
// app/api/appservice/[[...connect]]/route.ts
import { next13JsApiRouter } from "@/adapters/connect-nextjs13-adapter";
import routes from "@/connect"; // connect router with a service implementation
const { POST } = next13JsApiRouter({
routes,
prefix: "/api/appservice",
});
export { POST };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment