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

Middleware / ignore routes to be server by one when bundled with server #329

Closed
prabirshrestha opened this issue Dec 20, 2024 · 5 comments · Fixed by #358
Closed

Middleware / ignore routes to be server by one when bundled with server #329

prabirshrestha opened this issue Dec 20, 2024 · 5 comments · Fixed by #358
Labels
feature-request New feature or request

Comments

@prabirshrestha
Copy link

I'm bundling the one app with a rust server so a single binary serves both the rust server routes and the one spa app. There are some urls that I need one to ignore so GET on those routes would got to the server instead.

Is there something like navigateFallbackDenyList in one similar to the one that VitePWA supports?

https://vite-pwa-org.netlify.app/workbox/generate-sw#exclude-routes

@natew
Copy link
Collaborator

natew commented Dec 21, 2024

For now it's a bit awkward,

In dev you'd make a custom Vite plugin, see createServer in Vite. You can then hook into the vite server before. For production, you'd want to hook into the Hono app itself, and we just removed some of those hooks.

What we need is a middleware feature.

I think a _middleware.ts file anywhere in the fs routes would be good, sort of like Next.js:

Granted we do have loaders which can act as middleware essentially, they do receive the request and can throw or return Response, though we need better testing/docs around that still. There's also some trade-offs, so we'd need to think over it.

@natew natew added the feature-request New feature or request label Dec 21, 2024
@natew natew changed the title ignore routes to be server by one when bundled with server Middleware / ignore routes to be server by one when bundled with server Dec 21, 2024
@natew
Copy link
Collaborator

natew commented Dec 21, 2024

You could run your rust server on top of the One server for now too.

@prabirshrestha
Copy link
Author

One of my main goal is to have the app be a single binary with rust for speed on the server and rich SPA app for the web and iOS mobile app so bundling the one server would defeat the purpose.

Right now I'm setting the defaultRenderMode to be spa which I means I should be able to bundle the dist/client folder and server just index.html and the assets folder. From the dist folder I'm able to run a random http server and the SPA app does work. python3 -m http.server. There is redirect property for one.web config. I would like to have some mechanism on the client to ignore these routes similar as follows. since this is SPA only there should be no hono/one server configuration and should instead be a static configuration potentially in vite.config.ts.

    one({
      web: {
        defaultRenderMode: 'spa',
        redirects: [],
        ignoreRoutes: ['/signout', /^api/],
      });

The way I usually have done in the past is I have rust server handle all the routes and not found routes goes to the SPA app that is done by the rust proxy middleware. In prod it just always returns the index.html so I don't need another server for the client.

@natew natew mentioned this issue Jan 1, 2025
16 tasks
@natew
Copy link
Collaborator

natew commented Jan 1, 2025

Hm ok that makes sense.

I would like to have some mechanism on the client to ignore these routes similar as follows.

Not sure what you mean / what ignoreRoutes does? If you have your own Rust server you can ignore routes there right.

@natew natew closed this as completed in #358 Jan 3, 2025
@prabirshrestha
Copy link
Author

Here is a minimal repo.

  • Create a new Minimal+TamaGui app with bun one@latest.
  • Update app/index.ts with the following code to mimic.
import { Image } from "@tamagui/image-next";
import { Text, YStack } from "tamagui";
import { ToggleThemeButton } from "~/interface/ToggleThemeButton";
import oneBall from "../public/app-icon.png";
import { useEffect } from "react";

const makeApiRequest = async () => {
  try {
    const res = await fetch("/api/hello").then((res) => res.json());
    console.log(res);
  } catch (e) {
    console.error(e);
  }
};

export function HomePage() {
  useEffect(() => {
    makeApiRequest();
  }, []);
  return (
    <YStack bg="$color1" mih="100%" gap="$4" ai="center" jc="center" f={1}>
      <Text fontSize={20}>Hello, world</Text>
      <Image src={oneBall} width={128} height={128} />
      <ToggleThemeButton />
    </YStack>
  );
}
  • create a new bun app in a new folder. mkdir bun server && bun init && bun add hono.
  • update index.ts file with the following.
import { Hono } from "hono";
import { serve } from "bun";

const app = new Hono();

// API routes
app.all("/api/*", (c) => c.json({ ok: true }));

// SPA proxy
app.all("*", async (c) => {
  return await fetch("http://localhost:8081" + c.req.path);
});

serve({
  fetch: app.fetch,
  port: 3000,
});

Run bun dev in the one app. Notice the error in console and network tab. It is returning html with 200.

image

image

Now go to the server folder and run the server via bun index.ts. Ideally this would be my rust server with proxy during dev and embedded static files during prod. But right now seems like one is taking over fetch and I don't see any network request at all.

image

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

Successfully merging a pull request may close this issue.

2 participants