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/package.json b/frontend/package.json index b542fab..dc772eb 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", 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/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" ```