We need to be able to run the client and server on separate ports and still have them talk to each other. This maintains React's hot reloading capabilities without requiring the server to be running.
Resolves #5
Thought Process
I initially thought this was a CORS problem, and while it is, it's not necessarily a problem for purely local development. The only required change to link the two for local development is adding a proxy to package.json.
However, since we do plan to run this in a publicly available fashion, I decided to also tackle the CORS problem, which was relatively straightforward. Preferably, we'd like to not have to prepend all fetch calls on the client with the server address. Additionally, since the stdlib doesn't have a great way to manage middleware, and I had been looking for an opportunity to test my homegrown github.com/kevinfalting/mux module, I swapped it in.
I then wrote a CORS middleware and applied it to the top level mux.
Testing Steps
You can test that the proxy works by just running the client and server after adding the following snippet anywhere in the client:
You'll need to open the devtools console in your browser to see the output.
And then to test that the CORS is working, remove the "proxy": "http://localhost:8080", from the package.json file. You'll need to restart React after making this change. This will return some wacky error because it's no longer proxy-ing the request. You'll need to make the following change to the snippet you previously added to the client:
(async () => {
try {
const res = await fetch("http://localhost:8080/api/v1/events"); // here
console.log(await res.json());
} catch (e) {
console.log("failed to fetch:", e);
}
})();
Then you'll be getting the response successfully because of CORS.
Now, let's break it by turning off CORS. Comment the following line in cmd/eventual/main.go:
// middleware.CORS("http://localhost:3000"),
and rerun the server. The request should fail and output the following error in the browser's console:
Access to fetch at 'http://localhost:8080/api/v1/events' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
And that's that!
Risks
Doing it this way means that we're not really properly testing our CORS implementation, and if we change something that might violate it, without proper testing it will find it's way into production and break. The proxy trick is only relevant in development mode, so once we're ready to start publishing to the public, we'll have to revisit this. The assumption is that in production we'll be serving the client from the some origin as the server. A problem left for later.
Overview
We need to be able to run the client and server on separate ports and still have them talk to each other. This maintains React's hot reloading capabilities without requiring the server to be running.
Resolves #5
Thought Process
I initially thought this was a CORS problem, and while it is, it's not necessarily a problem for purely local development. The only required change to link the two for local development is adding a
proxy
topackage.json
.However, since we do plan to run this in a publicly available fashion, I decided to also tackle the CORS problem, which was relatively straightforward. Preferably, we'd like to not have to prepend all fetch calls on the client with the server address. Additionally, since the stdlib doesn't have a great way to manage middleware, and I had been looking for an opportunity to test my homegrown github.com/kevinfalting/mux module, I swapped it in.
I then wrote a CORS middleware and applied it to the top level mux.
Testing Steps
You can test that the proxy works by just running the client and server after adding the following snippet anywhere in the client:
npm start
go run ./cmd/eventual
And then to test that the CORS is working, remove the
"proxy": "http://localhost:8080",
from thepackage.json
file. You'll need to restart React after making this change. This will return some wacky error because it's no longer proxy-ing the request. You'll need to make the following change to the snippet you previously added to the client:Then you'll be getting the response successfully because of CORS.
Now, let's break it by turning off CORS. Comment the following line in
cmd/eventual/main.go
:and rerun the server. The request should fail and output the following error in the browser's console:
And that's that!
Risks
Doing it this way means that we're not really properly testing our CORS implementation, and if we change something that might violate it, without proper testing it will find it's way into production and break. The
proxy
trick is only relevant in development mode, so once we're ready to start publishing to the public, we'll have to revisit this. The assumption is that in production we'll be serving the client from the some origin as the server. A problem left for later.