Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add proxy middleware #33

Merged
merged 4 commits into from
Nov 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,36 @@

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);

/**
* Error handler; all errors thrown by server are handled here.
* 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) => {
Expand Down
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
19 changes: 13 additions & 6 deletions frontend/src/api/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -70,21 +77,21 @@ async function assertOk(response: Response): Promise<void> {
}

/**
* 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)
* @returns The Response object returned by `fetch()`
*/
export async function get(url: string, headers: Record<string, string> = {}): Promise<Response> {
// 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
Expand All @@ -96,13 +103,13 @@ export async function post(
body: unknown,
headers: Record<string, string> = {},
): Promise<Response> {
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
Expand All @@ -114,7 +121,7 @@ export async function put(
body: unknown,
headers: Record<string, string> = {},
): Promise<Response> {
const response = await fetchRequest("GET", url, body, headers);
const response = await fetchRequest("PUT", API_BASE_URL + url, body, headers);
Comment on lines -117 to +124
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@navidboloorian This was a little sloppy tbh, I should have looked more closely when reviewing

assertOk(response);
return response;
}
Expand Down
7 changes: 6 additions & 1 deletion writeup/part-0/0-2-Clone.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
```

<details>
Expand Down