The other responses seem to be answering how this would work once the hydration is occurring on the client side. I understood the question to be `Does the http request layer support doing API requests to routes which are on the same webserver as react-server`.
There doesn't appear to be special handling for this use case. However, they use SuperAgent (https://github.com/visionmedia/superagent) for http requests and I expect implementing the behavior that you're describing is relatively easy with their plugin system. Specifically I'd bet that plugins previously designed for testing could be used to accomplish your goal (superagent-mock or superagent-mocker).
What I'd like to be able to do is not incur an additional HTTP request against my own server. Does SuperAgent have a way to avoid opening a new socket when making a request against yourself?
Yeah, I understood what you wanted. I may not have been clear in my line of thinking. My understanding is that react-server does not support this. However, I do not believe that it would be difficult to add support using the testing plugins built for SuperAgent.
Imagine writing tests with mocked requests. Now apply that same logic to all calls to fetch() on the server. Does that make sense?
So to the front end when fetch() is called, it actually makes the request. On the server, when fetch() is called it hits a mock plugin which fetches "mocked" data which is just fetching data from whatever local store you normally would on your backend be it a JSON blob on the file system, a database or an in memory cache.
That's the opposite of what the question is asking for. They want to call fetch('/api/foo/bar') but on the client it does an HTTP call while on the server it recognizes that /api* is on the local system and therefore invoke that local route instead of doing an unnecessary http call.
That's what I'm apparently failing to describe how to accomplish :).
I'd like to know the answer to this too. What I've thought so far is that I just call the function that makes db calls or other operation on the server side but this is clearly not the way do in client side if the app was to be universal.
In my experience [1], you'd probably just use an if statement that does something different when you're on the server. That's totally fine and is still a universal app; universal apps don't have to take every exact same code path on the client and server, they just have to run the same code base.
In React, people typically use the ExecutionEnvironment module [2] for this:
if (ExecutionEnvironment.canUseDOM) {
// make client side request
} else {
// make direct db request
}
...but you could also just do some simpler check, like see if `window` exists, or make up your own `IS_SERVER` global, etc.
Next you'll wonder: won't that still ship the server-side code to the browser, even if it's not run, and pull in any server-only modules you're importing, e.g. database access stuff? No: you'd fix this with (for example) webpack's `DefinePlugin` [3], telling it that `ExecutionEnvironment.canUseDOM` should always be `true` wherever it occurs in your client-side JS bundle, and dead code elimination will then rip out those server-only `else` branches before that code gets shipped to the browser.
Or a similar setup, like wwalser hinted at: write 2 versions of your 'request' module: one for the client, and one for the server. Tell webpack it should point to the client-side one when you generate your client JS bundle. People use webpack because it lets you do all kinds of overrides like this.
[1]: I work at Formidable, we do a ton of React for big companies.
I'm actually working on an isomorphic app. My approach is to simply create a PersistenceService interface, with methods returning promises, and to make two classes implementing it, SqlPersistenceService and AjaxPersistenceService. You inject the correct instance when you create the server and when you create the client. No if needed, and as I'm using Typescript, the compiler ensures both SqlPersistenceService and AjaxPersistenceService will keep following the contract of PersistenceService in the future.
There doesn't appear to be special handling for this use case. However, they use SuperAgent (https://github.com/visionmedia/superagent) for http requests and I expect implementing the behavior that you're describing is relatively easy with their plugin system. Specifically I'd bet that plugins previously designed for testing could be used to accomplish your goal (superagent-mock or superagent-mocker).