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

Express page #29

Merged
merged 8 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
3 changes: 2 additions & 1 deletion pages/hack-school/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"git-github": "Git/GitHub",
"html": "Week 1: HTML",
"css": "Week 1: CSS",
"js": "Week 2: JavaScript"
"js": "Week 2: JavaScript",
"express": "Week 4: Building APIs with Express"
}
172 changes: 172 additions & 0 deletions pages/hack-school/express.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Week 4: Building APIs with Express.js

## What is Express?
[Express](https://expressjs.com) is a web application framework for Node.js that enables developers to start a local server and develop API routes. Express does
a good job of abstracting away the complexity of serving a web application. Before we explore Express, some background on the Internet and APIs is helpful!

## Background on the Internet

Before we explore Express.js, some background information on how servers work is necessary.

### How the Internet works

The internet can be thought of as a really, really long wire. Computers all over the world can interact with one another via this wire.
In prior chapters, we mentioned the idea of **clients**. Web **clients** are the users (technically, web browsers, like Chrome or Safari).
These clients request data through this long wire from web **servers**, which are simply any computers that serve data to client.

The standard of this client/server communication is a protocol known as HTTPS (Hypertext Transfer Protocol). This is a "language" that both
clients and servers can speak.

### HTTP Requests

We mentioned earlier that clients can request data from servers across the internet. This is accomplished with an HTTP Request, which is just
a way of telling the server what the client would like to do. There are four common HTTP methods:

- `GET`, for retrieving a resource from the server
- `POST`, for posting or adding a resource to the server
- `PUT`, for editing or modifying an existing resource on the server
- `DELETE`, for deleting an existing resource on the server

Together, these four methods give any application **CRUD functionality**–Create, Read, Update, Delete. Take a look at your favorite applications, and you'll be structured
to notice that all of them support some form of CRUD.

There are more [HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods), but the above four are the most common ones you'll see.

### HTTP Responses
For every request, there must be a response. Servers can respond to requests through an HTTP response. These responses have status codes tied to them, to indicate
to the client whether the request was successful, and any specific information if it was unsuccessful. You've definitely seen these before! Have you ever tried to buy tickets to an event,
but encountered a `500` (internal server error), or clicked on a link to be met with a `404` (resource not found error)?

Status codes are 3 digit numbers that are classified according to success level, client errors, server errors, etc. You can see a comprehensive list
of them [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)!

### Web application architecture

Putting our clients, servers, requests, and responses together, this is a standard web application architecture:

![image](pages/hack-school/images/webapparch.png)

To summarize, clients communicate with servers via HTTP requests and responses. When those requests and recieved and processed,
the server may make database queries to provide actual data for the client to use.

## APIs
Although there exists a standard for communication (HTTP), every server interacts differently. Imagine trying to `GET` a song from Spotify's servers, and then
attemping to `GET` a movie from Netflix's servers. While both requests are attempting to retrieve a resource, the way that one might ask for each differs. This is where
**APIs** come into play.

API stands for **A**pplication **P**rogramming **I**nterface. An API is simply a toolkit for a client to interact with. Every server is different and accomplishes different goals
through the use of this toolkit. APIs provide a framework and standard for how clients can interact with any given server.

A good analogy for APIs is that of a waiter in a restaurant. The tables and dining area is the client, where the customers send requests for food to the kitchen (Requests), which is the backend. The kitchen is responsible for creating
the food and sending it back to the dining area (Responses). How is this communication done? Through the waiters and waitresses! APIs are similar to waiters and waitresses, since they're the middlemen responsible for requests making it to the back-end, and
responses making it back to the client.

![image here](pages/hack-school/images/apiwaiter.png)
Source: monosolutions.com

Generally, APIs provide **API routes**, which are specific routes on a server that HTTP requests can be sent to. This allows clients to figure out how to interact with a particular server and request
a certain set of resources. API routes have the following syntax:

```
http://localhost:5000/api/purchases

```

The same API route can be used for different HTTP methods. For example, a GET request sent to this route might return all purchases, while a POST
request sent to this route (with a request body) would post a new purchase.

You can see this in action with the [Spotify API](https://developer.spotify.com/documentation/web-api)! Take a look at the endpoints for various routes, possible responses based on status code, and parameters for [GET Album](https://developer.spotify.com/documentation/web-api/reference/get-an-album).

nik-dange marked this conversation as resolved.
Show resolved Hide resolved

## Building our own APIs with Express

Now that we have a background on what APIs are and how we interact with them, we can discuss how Express enables developers to build their own APIs. Express abstracts away
the complexity in serving a web application, allowing developers to quickly set up and customize their application.

### Server setup
To get started, create a directory called `server` within your application.

Next, [initialize a Node.js application](https://docs.npmjs.com/cli/v10/commands/npm-init).
This is achieved by executing `npm init -y` in your terminal. The `-y` flag is a shortcut to allow default configurations.

```bash copy showLineNumbers
npm init -y
```

Now, we need to install Express as a package. [NPM (Node Package Manager)](https://www.npmjs.com) has hundreds of packages for developing applications, which you can see here.
We just need Express for now, so you can execute

```bash copy showLineNumbers
npm i express
```

which will install Express. You should notice a `package.json` file in your directory

Then, navigate inside this directory with `cd server` and create a file called
`index.js`. You can populate it with the following three lines:

```javascript copy showLineNumbers
const express = require('express');
const server = express();
server.listen(3000);
```

These three lines import Express, instantiates a server, and has it listening on your computer's `PORT 3000`. If you open your web browser and
go to `localhost:3000`, you can see the result of this API!

### Creating an API route

Now that Express is instantiated, we can add API routes. The following lines define a `GET` route:

```javascript copy showLineNumbers
const router = express.Router();
router.get('/purchases', async (req, res) => {
// fetch purchases from database
res.status(200).json({ purchase });
});
```

We begin by instantiating an Express router, which enables us to attach routes to our API.
Then, we define a `GET` route with arrow function syntax. This route is now live on `localhost:3000/purchases`, so sending a `GET` request
would return the `json` representation of `purchase`.

You'll notice that we have a callback function here too; an asynchronous function with `(req, res)` as parameters. If you guessed that these are
our **request** and **response** objects, you'd be correct! This is how our `GET` route can access the request and attach a status code to the response.

What if we want to get a specific purchase? This is where route parameters come into play. We can slightly adjust our route to take in a specific ID, and use it
to query from our database

```javascript copy showLineNumbers
router.get('/purchases/:id', async (req, res) => {

const purchaseId = req.params.id;

// fetch purchases from database
res.status(200).json({ purchase });
nik-dange marked this conversation as resolved.
Show resolved Hide resolved
});
```

We can do something similar with `POST` requests, we can utilize the `req` parameter to access details of our request body:

```javascript copy showLineNumbers
router.post('/purchases', async (req, res) => {

const purchase = req.body.purchase;

const name = purchase.name;

const {description} = purchase; // object destructuring

// log purchases to database
res.status(200).json({ purchase });
});
```

## Testing our API with Postman

It's always important to test APIs, just as you would test any software you build. Check out our section on testing with Postman!





Binary file added pages/hack-school/images/apiwaiter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pages/hack-school/images/webapparch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions theme.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const config: DocsThemeConfig = {
const url = `https://hack.acmucsd.com${
defaultLocale === locale ? asPath : `/${locale}${asPath}`
}`;
const title = frontMatter.title || 'ACM Hack at UCSD';
const title = frontMatter.title || 'ACM Hack at UC San Diego';
const description =
frontMatter.description ||
"ACM Hack at UCSD is a community focused on software engineering and exploring what's possible through code!";
"ACM Hack at UC San Diego is a community focused on software engineering and exploring what's possible through code!";

return (
<>
Expand All @@ -33,7 +33,7 @@ const config: DocsThemeConfig = {
{/* type of content */}
<meta property="og:type" content="website" />
{/* actual website title */}
<meta property="og:site_name" content="ACM Hack at UCSD" />
<meta property="og:site_name" content="ACM Hack at UC San Diego" />
{/* title to display for the specific link being shared */}
<meta property="og:title" content={title} />
{/* preview description text */}
Expand Down
Loading