Replies: 4 comments 4 replies
-
I don't think the DX is much worse? It's 2 main changes for route files, assuming you stick your server context into a single object in the context provider:
The DX for
I personally think of the Having separate |
Beta Was this translation helpful? Give feedback.
-
You nailed it right there @brophdawg11!! When I read that it was for "similarity to As I understand it, React Context benefits from Map-like approaches for performance -- zillions of components to render, lots of reading and writing going on, etc. Meanwhile server-side context touched perhaps a handful of times during the servicing of a request by maybe some middleware and then finally in a loader or action. Given that, I think the discoverability and type-safety wins out as well as the aforementioned developer familiarity , especially since back-end concepts and patterns are very stable and well-established; lots of solved problems unlike with front-end. I think for remix/RR new devs should find that it builds on concepts from web development that they might already know. Beyond being a curveball to backend devs, I think the pattern will confuse many front-end devs too. I don't think most could talk about how map and context are related as much as they can speak to how I argue that the average rank-and-file devs exposure to React context is using hooks like The obscure take also means LLM's are unlikely to be very helpful to struggling devs. I tried the new middleware in a playground app and vs. my previous project (first project ever in remix/RR) where I had a hono back-end and populated type-safe context (and also have full access to it via async local storage) it felt like a lot was missing. A degree of type safety was gone, IntelliSense suggestions were gone, and I actually had more code in my actions and loaders vs. when I could e.g. be in an action and type Especially coming from hono where types just work and get passed down auto-magically and just work it felt less elegant. RR has me editing Where does this lead ? Discussions like this one, I get where Sergio is coming from (at least I think I do). I think overall there's a risk of tending towards more complexity, and RR becoming more esoteric and obscure vs. easy and intuitive to pick up. I'd benchmark against patterns with custom back-end and would challenge if the dev X is not as smooth than a pure RR solution for context + middleware then its a sign. |
Beta Was this translation helpful? Give feedback.
-
I have some strong opinions on this topic, I'll probably be adding more comments after this one, but my biggest disagreement is with this:
I don't think that With Granted, there is limited flexibility/composability with However, I want to make clear that I don't think these things are mutually exclusive. I believe both approaches have their strengths and weaknesses, and more importantly serve different purposes.
Engineers can create a new route and immediately have access to the entire toolkit, no extra imports needed. This is not something I can provide with Regardless of whether or not there's a separate "bindings" or whatever you want to call it, the ability to provide a common set of... things... that are immediately available without any ceremony ( Removing that ability for little to no benefit would leave a bad impression on both me and my engineers. |
Beta Was this translation helpful? Give feedback.
-
DX and type safety aside, the new context API changes mean we can no longer inject external dependencies into RR which is critical functionality that has been removed. It needs to be reinstated through the bindings proposal or some other form to avoid needlessly breaking or preventing the ability to update RR apps |
Beta Was this translation helpful? Give feedback.
-
The new
RouterContextProvider
is great for middleware as you can safely read and write thereBut
AppLoadContext
is great for cases where the HTTP server does need to inject things into RR apps, this is more common in CF apps where you receive D1, KV, R2, etc. bindings fromAppLoadContext
in your RR app, but it's also something apps may need to do with getLoadContext in other servers, for multiple reasons, specially when supporting older infrastructure.This is why I thought that to keep both ideas, context can be repurposed for
RouterContextProvider
for middleware usage, and introduce abindings
argument (typed asServerBindings
interface) that can be used by server adaptersSo in CF or another server you can do
Where bindings here is a
ServerBinding
object, and the server is in charge of typing itBut I would do a difference here, I would type loader, action and middleware args as
Readonly<AppLoadContext>
, and at runtime freeze the object too.Then in one of those functions you will do:
To ensure this bindings are considered something that RR apps only can read, but not change at runtime, if you want that use
RouterContextProvider
.This is not only useful for CF apps that will be able to keep accessing CF bindings this server, but also other apps like Express that may need to support old code like maybe a data layer and inject it into RR
I know I can do this with
RouterContextProvider
by returning aMap
ingetLoadContext
.But
AppLoadContext
is just simpler to use, and gives a better DX for any code that doesn't need to be in a middleware.As you don't need to import anything (e.g. import the context object), and you can just do
context.something
, and you knowsomething
will be there because your HTTP server is in charge of passing itThe
RouterContextProvider
should be limited to only middleware functions and not for the HTTP server usage instead.Beta Was this translation helpful? Give feedback.
All reactions