1 of 38

Hack Session #5

API Development

Find and sit with your�Group and Mentor!

2 of 38

SANDBOX <> OASIS

  • 3/14 6-7 PM, DODGE 119
  • ARTS AND CRAFTS

3 of 38

  • Refresher 🧠
  • APIs📡
  • Demo 🛒
  • Hack Time 🪓

Agenda

4 of 38

⏱️ Project Series Timeline

HS 0 / EX 0

Git

(1/18)

HS 1 / EX 1

Web Basics

(1/25)

HS 2

React

(2/1)

HS 3

React Continued

(2/8)

HS 4

Databases

(2/22)

HS 5

API Development

(3/8)

HS 6

Co-op Panel

(3/15)

END

Demo Day

(TBD)

HS 7

Auth

(3/22)

HS 8

Deployment

(3/29)

0

1

2

3

4

5

6

7

8

E

5 of 38

Refresher 🧠

(before we build up)

6 of 38

CRUD

Create

Add new data

Read

Get existing data

Update

Change existing data

Delete

Remove data

  • The 4 basic operations of working with data:

7 of 38

Database

  • Organized place to store information
  • Can be easily accessed, managed, and updated

8 of 38

Tables

  • Collection of related data
  • Organized into rows and columns
  • Each table represents a different type of data

Courses

Ratings

etc.

9 of 38

Columns

  • Particular attribute of data being stored
  • Each piece of info is stored in a�separate column
  • Can have any number of columns in�a database

id

Courses

course_code

course_name

last_run

etc.

10 of 38

Keys

  • Uniquely identify a specific row
  • Used to establish relationships between tables
  • Types of Keys
    • Primary Key: Unique identifier (usually id)
    • Foreign Key: References another table's primary key
    • Unique: Value must be unique

course_code

course_name

last_run

etc.

id

first_run

text

text

uuid

date

date

11 of 38

APIs📡

12 of 38

Quick Check-In

So far we have built …

  • Frontend (React)
  • Database (Supabase)
  • We still need
    • … a backend server that provides an API for our frontend to communicate with.
    • The backend contains the business logic and talks to the database, while the API is the interface that defines how the frontend can interact with it

13 of 38

The Problem

Connecting to Supabase directly from our react frontend is insecure and suboptimal!

  • Without RLS, anyone with the public anon key can access/modify data
    • Can't use secret API keys (Stripe, OpenAI, etc.) - they'd be exposed in browser
  • No validation
    • Someone could submit bad data that could break our app
  • Duplicate logic for mobile/web apps
    • You would have to connect each frontend to the database separately

14 of 38

The Solution: Build an API!

React Frontend ↔ Your API ↔ Supabase Database

  • API keys stay secret on the server
  • Validate data before it hits the database
  • Multiple apps (web, mobile, desktop) can use the same API!
  • Handle complex business logic securely

15 of 38

Real World Examples

You interact with APIs every day!

  • Instagram: Fetching posts, liking photos
  • Spotify: Getting playlists, playing songs
  • Weather apps: Getting forecast data
  • Video games: Leaderboards, multiplayer

Every button you click, every post you see = API call happening behind the scenes

16 of 38

What is an API?

  • API stands for Application Programming Interface
  • An API is like a messenger between two applications.
  • It receives a request, talks to some other system (database) and sends back a response.

Think of it as a waiter at a restaurant:

  • You (client) look at menu and order
  • Waiter (API) takes your order to kitchen
  • Kitchen (database) prepares the food
  • Waiter brings food back to you
  • You enjoy your meal!

17 of 38

API Endpoints

Endpoint = A location within an API where a client can send requests

  • Think of endpoints like functions you can call over the internet:
    • GET /api/listings → Get all listings
  • Each endpoint has:
    • A URL path (/api/listings)
    • An HTTP method (GET, POST, etc.)
    • A specific job to do

18 of 38

HTTP: How the Web Talks

APIs use HTTP - the same system that loads web pages

  • HTTP = HyperText Transfer Protocol
  • Every communication between your frontend and backend happens through:
    • HTTP Request (Frontend → Backend)
    • HTTP Response (Backend → Frontend)
  • Let's break down what's in each...

19 of 38

HTTP Request Components

Every HTTP Request Has

URL: Defines where the request is going

localhost:8000/api/listings

Method: What action you want to perform

GET, POST, PUT, DELETE (We’ll explain more in depth next)

Headers: Extra information about the request. Could include information regarding …

Authentication (who you are), Content Type (the format that the data is in)

Body: The data you’re sending (this is optional - not used with GET or DELETE)

{ "title": "Calculus Book" }

20 of 38

HTTP Methods Explained

Method

CRUD

Purpose

Has Body?

Example

GET

READ

Retrieve data

NO

Get all listings

POST

CREATE

Add new data

YES

Create new listing

PUT/PATCH

UPDATE

Modify existing data

YES

Update listing price

DELETE

DELETE

Remove data

NO

Delete a listing

21 of 38

HTTP Response Components

Every HTTP Response Has

Status Code: What happened with your request

200 OK, 404 Not Found, etc. (Will explain in detail next)

Headers: Response metadata

Date, server information, etc.

Body: The data you get back

JSON (Will explain soon) data from database e.g [{ "id": 1, "title": "Calculus Book", "price": 45 }]

22 of 38

Status Codes

  • 2xx - Success!
    • - 200 OK: Request succeeded
    • - 201 Created: New resource created
  • 4xx - You messed up
    • - 400 Bad Request: Malformed request
    • - 401 Unauthorized: Need to log in
    • - 403 Forbidden: Logged in but can't access
    • - 404 Not Found: Resource doesn't exist
  • 5xx - Server messed up
    • - 500 Internal Server Error: Something broke on server
    • - 503 Service Unavailable: Server is down

You saw "Status Code" in the HTTP Response - here's what those numbers mean:

23 of 38

JSON (JavaScript Object Notation)

  • APIs usually send data in JSON format
  • It is extremely lightweight, language-independent, and easy to read.
  • JSON
    • Looks like JavaScript objects
    • Easy for both computers/humans to understand
    • Works across any language

Example

24 of 38

REST Architecture

REST = Representational State Transfer

  • A popular pattern for organizing APIs into predictable, logical structures
  • Why REST matters: Without REST, every API would have different patterns. REST provides predictable patterns - if you know one REST API, you can understand others

REST APIs use:

  • HTTP methods for actions (GET, POST, PUT, DELETE)
  • URLs for resources (nouns like /listings, not verbs like /getListings)
  • Standard status codes (200, 404, 500, etc.)
  • JSON for data

Result: APIs become intuitive and consistent across different applications

25 of 38

RESTful Routing Pattern

Method

Action

Endpoint

Description

GET

Read

/listings

Retrieve data

POST

Create

/listings

Add new data

PUT/PATCH

Update

/listings/:id

Modify data

DELETE

Delete

/listings/:id

Remove data

Notice the pattern:

  • Collection: listings
  • Specific item: listings/:id

26 of 38

What is Express.js?

  • Express.js = Node.js framework for building APIs
  • It makes it really simple to:
    • Handle HTTP requests
    • Define API endpoints
    • Connect to databases
    • Send back JSON responses
  • Without express (raw Node.js)
    • Write network code manually
    • Parse requests yourself
    • Handle routing manually

27 of 38

How Express Works

  • When you visit an endpoint like /listings
    • The browser first sends a request to the server
    • Express matches it to a route
    • Express runs the function
    • You send back a response with res.json()
  • You just define the functions/rules for what your API should do when a certain endpoint is hit.

Browser sends request

Express matches to route

Express runs function

Send back response

28 of 38

A Simple Endpoint

Let’s look at a very simple endpoint:�// GET endpoint - returns JSON

app.get('/api/hello', (req, res) => {

res.json({

message: 'Welcome to the API!',

timestamp: new Date() }); });

  • When someone visits http://your-url:3000/api/hello
  • Express runs this function
  • Sends back JSON with a message and current time

29 of 38

BUILDING APIS WITH EXPRESS - KEY CONCEPTS

1. Middleware

  • Functions that process requests before they reach your routes
  • Handle tasks like parsing JSON, authentication, logging

2. Async/Await

  • Handle operations that take time (database queries, API calls)
  • JavaScript doesn't wait by default - async/await makes it wait

3. Error Handling

  • Catch and handle errors gracefully
  • Return appropriate status codes
  • Prevent server crashes

30 of 38

Middleware

Middleware = Functions that execute during the request-response cycle

  • Think of middleware as an assembly line - every request passes through a series of checkpoints before reaching your route handler.
  • How Middleware Works:
    • Request comes in
    • Passes through middleware in order (top to bottom)
    • Each middleware can modify req or res objects
    • Calls next() to pass control to the next middleware
    • Finally reaches your route handler
  • Example: Logging middleware - runs for EVERY request

app.use((req, res, next) => {

console.log(`${req.method} ${req.url} - ${new Date()}`);

next(); });

31 of 38

CORS Middleware

CORS = Cross-Origin Resource Sharing

What is CORS? CORS is a browser security feature that controls which websites can access your API. By default, browsers block requests between different origins (different domains or ports).

The Problem:

  • Your React app runs on http://localhost:5173
  • Your Express API runs on http://localhost:3000
  • These are different origins (different ports), so browsers block the requests

The Solution: CORS middleware tells the browser "it's okay to accept requests from my frontend"

app.use(cors({ origin: 'http://localhost:5173' }));

  • What this does:
    • Adds special headers to responses
    • Browser sees these headers and allows the request
    • In production, you'd specify your actual domain

32 of 38

ASYNC/AWAIT

The Challenge: JavaScript doesn't wait by default

  • JavaScript is non-blocking - it continues executing code while waiting for slow operations like database queries.
  • Asynchronous functions allow us to bypass this with the following

app.get('/api/listings', async (req, res) =>

{ const { data } = await supabase.from('listings').select('*');

res.json(data); // Now data has the results });

How it works:

  • async keyword: Marks function as asynchronous
  • await keyword: Pauses execution until the operation completes
  • Code after await only runs when data is ready
  • Other requests can still be processed (non-blocking)

33 of 38

Error Handling

Why Error Handling Matters: Without proper error handling, a single error can crash your entire server. Error handling ensures your API stays online and provides helpful feedback when things go wrong.

The Pattern: try-catch blocks

app.get('/api/listings/:id', async (req, res) => {

try { // Your code that might fail

} catch (error) {

res.status(500).json({ error: 'Failed to fetch listing' }); } });

Best Practices:

  • Validate input!

if (!title || !price) { return res.status(400).json({ error: 'Missing required fields' }); }

  • Use appropriate status codes: 400 - Bad Request, 404 - Not Found, 500 - Server Error
  • Always wrap async operations in try-catch to handle potential failures

34 of 38

Complete Endpoint - Putting it All Together

Middleware

Endpoint

35 of 38

Demo 🛒

36 of 38

Attendance

37 of 38

Hack Time 🪓

38 of 38

See you next Sunday, Project Series Cohort!

Follow us on Instagram @oasisneu, and check out our website! oasisneu.com

Feel free to ask us�any questions!