From c39d258d59dbad5405a543c202a93f89812ffd73 Mon Sep 17 00:00:00 2001 From: Navid Boloorian Date: Thu, 2 Nov 2023 23:45:53 -0700 Subject: [PATCH 1/4] added proxy middlware --- frontend/package-lock.json | 1 + frontend/package.json | 2 +- frontend/src/setupProxy.js | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frontend/src/setupProxy.js diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 044ba7e..fc0a9de 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,6 +15,7 @@ "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", + "http-proxy-middleware": "^2.0.6", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", "react": "^18.2.0", diff --git a/frontend/package.json b/frontend/package.json index b542fab..03b900a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,7 +2,6 @@ "name": "frontend", "version": "0.1.0", "private": true, - "proxy": "http://localhost:3001", "type": "module", "dependencies": { "@testing-library/jest-dom": "^5.17.0", @@ -12,6 +11,7 @@ "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", + "http-proxy-middleware": "^2.0.6", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", "react": "^18.2.0", diff --git a/frontend/src/setupProxy.js b/frontend/src/setupProxy.js new file mode 100644 index 0000000..bc27a80 --- /dev/null +++ b/frontend/src/setupProxy.js @@ -0,0 +1,11 @@ +import createProxyMiddleware from "http-proxy-middleware"; + +export default function (app) { + app.use( + "/api", + createProxyMiddleware({ + target: "http://localhost:3001", + changeOrigin: true, + }), + ); +} From d4118b81093ef2b8a6bcca327f6ef35ddbb8fe4a Mon Sep 17 00:00:00 2001 From: William Wu Date: Fri, 3 Nov 2023 14:07:39 -0700 Subject: [PATCH 2/4] Make a better fix with env vars and CORS headers --- backend/src/app.ts | 20 +++++++++++++++----- frontend/src/api/requests.ts | 19 +++++++++++++------ frontend/src/setupProxy.js | 11 ----------- 3 files changed, 28 insertions(+), 22 deletions(-) delete mode 100644 frontend/src/setupProxy.js diff --git a/backend/src/app.ts b/backend/src/app.ts index cb5077a..df6506a 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -4,14 +4,26 @@ import "dotenv/config"; import express, { NextFunction, Request, Response } from "express"; +import cors from "cors"; import { isHttpError } from "http-errors"; import taskRoutes from "src/routes/task"; const app = express(); -// initializes express to accept json in the request/response body +// initializes Express to accept JSON in the request/response body app.use(express.json()); +// sets the "Access-Control-Allow-Origin" header on all responses to allow +// requests from the frontend, which has a different origin - see the following +// pages for more info: +// https://expressjs.com/en/resources/middleware/cors.html +// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin +app.use( + cors({ + origin: process.env.FRONTEND_ORIGIN, + }), +); + app.use("/api/task", taskRoutes); /** @@ -19,11 +31,9 @@ app.use("/api/task", taskRoutes); * Explicit typings required here because TypeScript cannot infer the argument types. * * An eslint-disable is being used below because the "next" argument is never used. However, - * it is still required for express to recognize it as an error handler. For this reason, I've + * it is still required for Express to recognize it as an error handler. For this reason, I've * disabled the eslint error. This should be used sparingly and only in situations where the lint - * error cannot be fixed in another way. Alternatively, the variable name can be prefixed with an - * underscore (i.e. _next). Use underscores for variables that are unused but are still required. - * In this case, eslint-disable is used for educational purposes. + * error cannot be fixed in another way. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars app.use((error: unknown, req: Request, res: Response, next: NextFunction) => { diff --git a/frontend/src/api/requests.ts b/frontend/src/api/requests.ts index 095e7d9..e17818e 100644 --- a/frontend/src/api/requests.ts +++ b/frontend/src/api/requests.ts @@ -8,6 +8,13 @@ */ type Method = "GET" | "POST" | "PUT"; +/** + * The first part of the backend API URL, which we will automatically prepend to + * every request. This means in the rest of our code, we can write "/api/foo" + * instead of "http://localhost:3001/api/foo". + */ +const API_BASE_URL = process.env.REACT_APP_API_BASE_URL; + /** * A wrapper around the built-in `fetch()` function that abstracts away some of * the low-level details so we can focus on the important parts of each request. @@ -70,7 +77,7 @@ async function assertOk(response: Response): Promise { } /** - * Sends a GET request to the provided URL. + * Sends a GET request to the provided API URL. * * @param url The URL to request * @param headers The headers of the request (optional) @@ -78,13 +85,13 @@ async function assertOk(response: Response): Promise { */ export async function get(url: string, headers: Record = {}): Promise { // GET requests do not have a body - const response = await fetchRequest("GET", url, undefined, headers); + const response = await fetchRequest("GET", API_BASE_URL + url, undefined, headers); assertOk(response); return response; } /** - * Sends a POST request to the provided URL. + * Sends a POST request to the provided API URL. * * @param url The URL to request * @param body The body of the request, or undefined if there is none @@ -96,13 +103,13 @@ export async function post( body: unknown, headers: Record = {}, ): Promise { - const response = await fetchRequest("POST", url, body, headers); + const response = await fetchRequest("POST", API_BASE_URL + url, body, headers); assertOk(response); return response; } /** - * Sends a PUT request to the provided URL. + * Sends a PUT request to the provided API URL. * * @param url The URL to request * @param body The body of the request, or undefined if there is none @@ -114,7 +121,7 @@ export async function put( body: unknown, headers: Record = {}, ): Promise { - const response = await fetchRequest("GET", url, body, headers); + const response = await fetchRequest("PUT", API_BASE_URL + url, body, headers); assertOk(response); return response; } diff --git a/frontend/src/setupProxy.js b/frontend/src/setupProxy.js deleted file mode 100644 index bc27a80..0000000 --- a/frontend/src/setupProxy.js +++ /dev/null @@ -1,11 +0,0 @@ -import createProxyMiddleware from "http-proxy-middleware"; - -export default function (app) { - app.use( - "/api", - createProxyMiddleware({ - target: "http://localhost:3001", - changeOrigin: true, - }), - ); -} From 2ab44e5f73f83f1e5ff0db2d6e7a7a7f534bb499 Mon Sep 17 00:00:00 2001 From: William Wu Date: Fri, 3 Nov 2023 14:08:09 -0700 Subject: [PATCH 3/4] Update writeup with new .env files --- writeup/part-0/0-2-Clone.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/writeup/part-0/0-2-Clone.md b/writeup/part-0/0-2-Clone.md index 35bbfbd..df4852a 100644 --- a/writeup/part-0/0-2-Clone.md +++ b/writeup/part-0/0-2-Clone.md @@ -36,10 +36,15 @@ You should now have a copy of all the starter code in the folder you selected. We're almost ready to run the project for the first time! Before we can do that, we just need to add some environment variables required by the code. 1. Open the repo in VS Code (File > Open Folder, then select the root folder of the repo). In the `backend` folder, create a new file named `.env`. -2. Paste the following into the .env file: +2. Paste the following into the `.env` file: ``` PORT=3001 MONGODB_URI="mongodb://127.0.0.1:27017/todoList" + FRONTEND_ORIGIN="http://localhost:3000" + ``` +3. Create another `.env` in the `frontend` folder: + ``` + REACT_APP_API_BASE_URL="http://localhost:3001" ```
From 6c845e249d8159ffc561b60f85d4d6bfb176d212 Mon Sep 17 00:00:00 2001 From: William Wu Date: Fri, 3 Nov 2023 14:13:32 -0700 Subject: [PATCH 4/4] Uninstall `http-proxy-middleware` --- frontend/package-lock.json | 1 - frontend/package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fc0a9de..044ba7e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,7 +15,6 @@ "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", - "http-proxy-middleware": "^2.0.6", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", "react": "^18.2.0", diff --git a/frontend/package.json b/frontend/package.json index 03b900a..dc772eb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,7 +11,6 @@ "@types/node": "^16.18.38", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", - "http-proxy-middleware": "^2.0.6", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", "react": "^18.2.0",