x-remix-id header #2904
Replies: 8 comments
-
I know it is a detail but the Maybe it would be better to follow their suggestions? |
Beta Was this translation helpful? Give feedback.
-
It's still a very strong convention that a lot of libraries follow 🤷♂️ I don't really care either way. |
Beta Was this translation helpful? Give feedback.
-
That's true, still a lot of X-headers everywhere. I probably wrote it because I recently discovered it when trying to convince someone that we should create an But maybe as Remix and MDN docs are best friends, the authors of Remix would want to stick to the recommendations 😄 |
Beta Was this translation helpful? Give feedback.
-
Personally I like the prefix despite the recommendation because it communicates that the header is custom and not standard |
Beta Was this translation helpful? Give feedback.
-
I've actually implemented a POC. You can check it out here: https://remix-playground.herokuapp.com/ |
Beta Was this translation helpful? Give feedback.
-
Yeah this is a good feature. The whole point is for a server to be able to associate the multiple, parallel requests Remix sends with a single, client side navigation. Primary use case is being able to share an inflight query between them. For example, if you go from "/inbox" to "/invoices/123", three loaders will be called as
Remix will send off three fetch requests and each one of them may hit the database to check the user's permissions:
All of this information can be retrieved with a single query like Instead of all three loaders hitting the database with the same query, this header would allow servers to share the query with a simple inflight cache keyed by the x-remix-nav-id header. // app/models/user.js
export let inflightCache = new Map();
export function getPermissions(request, userId) {
let navId = request.headers.get("X-Remix-Nav-Id");
let inflight = inflightCache.get(navId);
if (inflight) {
return inflight;
}
let promise = db.getUserPermissions(userId);
inflightCache.set(navId, promise);
return promise.finally(() => inflightCache.delete(navId))
}
// root.js, invoices.js, $invoice.js
// can now all just call this function and a single db call will be shared
// for each fetch request coming in for the same nav id
import { getPermissions } from "../models/user"
export async function loader({ request } ) {
let user = await getUserSession(request);
return await getPermissions(request, user.id)
} Notes
|
Beta Was this translation helpful? Give feedback.
-
I think you can use crypto.getRandomValues for now until this https://github.com/WICG/uuid is ready, from the dev using Remix perspective we know that header comes and is supposed to be unique, we should rely on it being uuid or number or date or anything |
Beta Was this translation helpful? Give feedback.
-
I noticed that you're using That's why I added the loader count in my implementation, so I could keep track of the requests in flight and then cleanup the cache once all loaders have finished. Anyway, the more I've played with it, the more I believe that client-side transitions should be sent as a single request. This makes the server-side processing consistent regardless of the type of transition. It also enables caching for providers that may process different loader requests on separate hosts. It just makes it simpler to reason about:
I'm not sure if that's too big a change at this point in time. I just feel that it might confuse people in the long run. |
Beta Was this translation helpful? Give feedback.
-
So we can associate all transition requests together due to the parallel nature of multiple requests and cache things good...
Sorry, my brain isn't working well. Here's the conversation: https://discord.com/channels/770287896669978684/771068344320786452/870486885435310090
Beta Was this translation helpful? Give feedback.
All reactions