Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[connect-next] Example using new app routing #542

Open
AshotN opened this issue Mar 16, 2023 · 8 comments
Open

[connect-next] Example using new app routing #542

AshotN opened this issue Mar 16, 2023 · 8 comments
Labels
enhancement New feature or request

Comments

@AshotN
Copy link

AshotN commented Mar 16, 2023

Is your feature request related to a problem? Please describe.
I noticed there is a new package to work with NextJS but the example is based on Next 12.

Describe the solution you'd like
I would appreciate some documentation on best practices when working with Next 13.

Describe alternatives you've considered
Using the Next 12 pages style

@AshotN AshotN added the enhancement New feature or request label Mar 16, 2023
@nicole0707
Copy link

I tries to integrate Connect with Next via Middleware, there is an issue on Edge Runtime. It only supports subset of available Node.js APIs.

@timostamm
Copy link
Member

@AshotN, the new app directory in Next.js is still an experimental opt-in. We do not support it yet.

@AshotN
Copy link
Author

AshotN commented Mar 18, 2023

Are there any plans for the near future?

@timostamm
Copy link
Member

Hey @AshotN, yes we plan to support it. The first step was #575 - it adds support for creating handlers using the fetch Request/Response types, which the new Route Handlers are using under the hood.

@timostamm
Copy link
Member

Related discussion for support for edge runtimes: #829

@samlee64
Copy link

Any update on this?

@lourd
Copy link

lourd commented Jun 24, 2024

I just set this up myself this weekend, it was pretty straightforward. I used the cloudflare workers example as reference. Here's the code others can use:

import {
  ConnectRouter,
  ConnectRouterOptions,
  createConnectRouter,
} from "@connectrpc/connect"
import {
  UniversalHandler,
  universalServerRequestFromFetch,
  universalServerResponseToFetch,
} from "@connectrpc/connect/protocol"

interface HandlerOptions extends ConnectRouterOptions {
  /**
   * Route definitions.
   */
  routes: (router: ConnectRouter) => void
  /**
   * The directory/prefix in which the Connect RPC server is mounted.
   */
  prefix: string
}

/**
 * Creates Next.js app route handlers for the given Connect service routes.
 */
export function nextAppRouter({ routes, prefix, ...options }: HandlerOptions) {
  const router = createConnectRouter(options)
  routes(router)
  const paths = new Map<string, UniversalHandler>()
  for (const handler of router.handlers) {
    paths.set(prefix + handler.requestPath, handler)
  }
  async function handler(req: Request) {
    const url = new URL(req.url)
    const handler = paths.get(url.pathname)
    if (handler === undefined) {
      return new Response(undefined, { status: 404 })
    }
    const uReq = universalServerRequestFromFetch(req, {})
    const uRes = await handler(uReq)
    return universalServerResponseToFetch(uRes)
  }
  return {
    POST: handler,
    GET: handler,
  }
}
// app/rpc/[[...connect]]/route.ts

export const { GET, POST } = nextAppRouter({
  prefix: "/rpc",
  routes(router) {
    // Register your service implementations here
    router.service(MyService, myServiceImpl)
  },
})

Mounting it at /rpc was of course an arbitrary choice, you could do /connect or wherever else, too. Your directory just needs to match your prefix parameter.

Are there other methods that need to be handled other than GET and POST? Maybe OPTIONS for people needing CORS? I didn't need that for my use case, and would be trivial enough to make your own OPTIONS handler function there to return the appropriate headers.

Hopefully this gets incorporated into a new plugin package or official example!

@ivanvanderbyl
Copy link

Thanks @lourd !! that worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants