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

support for non-React API endpoints #329

Open
Tracked by #24
himself65 opened this issue Dec 28, 2023 · 17 comments
Open
Tracked by #24

support for non-React API endpoints #329

himself65 opened this issue Dec 28, 2023 · 17 comments
Assignees

Comments

@himself65
Copy link
Contributor

himself65 commented Dec 28, 2023

I want to extend the Vercel serverless function to support non-react functions like AI stream(text stream), JSON response.

vercel edge function example:

import { connectMiddleware } from 'waku'
import { OpenAIStream, StreamingTextResponse } from 'ai';
import OpenAI from 'openai';

export default async function handler(req: Request, res: Response) {
  if (req.url === '/api/ai') {
    const { messages } = await req.json();

    const response = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      stream: true,
      messages,
    });

    const stream = OpenAIStream(response);

    return new StreamingTextResponse(stream);
 } else {
    connectMiddleware(/* ... */)
 }
}

Related discussion: #290

@dai-shi
Copy link
Owner

dai-shi commented Dec 28, 2023

Please provide description.

@dai-shi
Copy link
Owner

dai-shi commented Jan 3, 2024

I want to extend the Vercel serverless function to support non-react functions

I would create another serverless function and configure routes. It's true that there is no direct support for such use cases.

@dai-shi dai-shi mentioned this issue Jan 6, 2024
87 tasks
@dai-shi dai-shi self-assigned this Jan 11, 2024
@himself65
Copy link
Contributor Author

himself65 commented Jan 11, 2024

I used next.js days ago. I found that they support multiple runtimes on the same platform. edge and runtime. just one const https://github.com/himself65/npm-download-stat/blob/74973f915c65c521c396e726f40be97b9cc926c0/src/app/%5Bpkg%5D/page.tsx#L20C1-L20C31

export const runtime = "edge";

I'm not sure if waku providing createPage with runtime would be a good option

@himself65
Copy link
Contributor Author

Full JS environment people are using

  • Node.js (18/20)
  • Edge
  • Deno
  • Bun
  • Cloudflare worker

@dai-shi
Copy link
Owner

dai-shi commented Jan 12, 2024

We are taking a different approach. Waku core is designed completely with web standard, and provides wrappers for each runtime. (And I'm not a big fan of export const ... for configuring compiler behavior.)

That said, we care DX for supporting different runtimes. Will see.

@dai-shi dai-shi changed the title support extend cloudflare/vercel/deno middleware support middleware and custom (non-React) routes Feb 6, 2024
@dai-shi
Copy link
Owner

dai-shi commented Feb 6, 2024

I want try something soon, but can't tell what it's going to be like yet.

@campbellman
Copy link

@dai-shi I don't expect this to be the most robust solution, but I hacked a little solution together to make custom middleware and non-react endpoints possible via a src/api.ts file (customizable via waku.config.ts).

PR in my fork: campbellman#1
Example usage: https://github.com/campbellman/waku/tree/issue-329-custom-middleware/examples/14_minimal-api

I can clean this up, add tests, and submit an actually PR if it's something that aligns with your goals for the project. Otherwise, consider it a little experiment.

Love this project btw :)

@dai-shi
Copy link
Owner

dai-shi commented Feb 12, 2024

Thanks. It's probably similar to something I have in mind. I will refactor things. Please wait for it. (Lots of bug fixes are required before adding features. Please see "help wanted" issues.)
Your review and so on will be important when I finish my draft.

Meanwhile, enjoy experiments.

@dai-shi
Copy link
Owner

dai-shi commented Feb 20, 2024

I moved a task related to this to #513.

@dai-shi dai-shi changed the title support middleware and custom (non-React) routes support extend cloudflare/vercel/deno middleware Feb 20, 2024
@dai-shi
Copy link
Owner

dai-shi commented Feb 20, 2024

And, reverted to the original issue.

Here's my first question.
Do people want a separate serverless function for API routes, or embed it in our framework (meaning a combined serverless function).
In the case of former, it's probably out of the scope, because it's cloud environment specific.

For the second question,
as in #290, should we follow /api folder like in Next.js?

@dai-shi dai-shi changed the title support extend cloudflare/vercel/deno middleware support for non-React API endpoints Feb 20, 2024
@dai-shi
Copy link
Owner

dai-shi commented Feb 20, 2024

Changed the title again.

@campbellman
Copy link

Embedding + an /api folder is my vote.

Though this might require additional work to prevent polluting the global namespace server-side (

// HACK for react-server-dom-webpack without webpack
).

For example, app-root-path broke when I imported it into the same node process as waku.

@dai-shi
Copy link
Owner

dai-shi commented Feb 21, 2024

I'll add "Use it at your own risks" warning. 😄

@himself65
Copy link
Contributor Author

Do people want a separate serverless function for API routes, or embed it in our framework (meaning a combined serverless function).
In the case of former, it's probably out of the scope, because it's cloud environment specific.

I recently encountered this non-react API issue. I'm developing a React component that need to fetch /api/xxx, but here is two issue and my workaround

First I use custom nodejs + hono.

const app = new Hono();

app.get('/api/xxx', c => c.text('xxx'))

But I cannot fetch this API in react, I don't know the current server port, so my workaround be like:

const env = {
  ...process.env,
  MAIN_PORT: `${port}`,
};
if (isDev) {
  const { unstable_honoMiddleware: connectMiddlewareDev } = await import(
    "waku/dev"
  );
  hono.use(
    connectMiddlewareDev({
      env,
      ssr: false,
    }),
  );
}
if (!getEnv("MAIN_PORT")) {
  // waku build try to SSR the code
  return doc;
}
const port = +(getEnv("MAIN_PORT") as string);
const userDataPath = await fetch(
  `http://localhost:${port}/path/userData`,
).then((res) => res.text());

Second, you can see from the example code that Waku still wanna SSR the code in build time, even though I disabled SSR (dai-shi also said this is Intentional), but it's a little confusing.

Imaging I'm building a react app, and one of RSCs called database uses a dev database in my local environment. Because of this behavior, I think waku build will at least leak the dev data to the product code.

Not sure how @dai-shi think about this

@dai-shi
Copy link
Owner

dai-shi commented Feb 27, 2024

But I cannot fetch this API in react

Do you mean a server component to fetch an api on the same server?
I thought the API endpoints are for clients.

Waku still wanna SSR the code in build time, even though I disabled SSR

Even if we disable SSR for waku build?
Anyway, I think the solution is render: 'dynamic' with createPages. Or, I might be missing something. In that case, can you open a new discussion?

@himself65
Copy link
Contributor Author

himself65 commented Feb 27, 2024

Even if we disable SSR for waku build?
Anyway, I think the solution is render: 'dynamic' with createPages. Or, I might be missing something. In that case, can you open a new discussion?

I found that it's a bug, opening an issue

#543

@dai-shi
Copy link
Owner

dai-shi commented Mar 5, 2024

We have a low-level solution, "middleware".
Please play with it and give us feedback. #513 (comment)

@dai-shi dai-shi mentioned this issue Jun 6, 2024
dai-shi added a commit that referenced this issue Jun 9, 2024
While we wait for #329 (which takes time to design and implement, and we
believe most cases are covered by server actions), we can use the
low-level middleware api.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants