Skip to content

RESTful APIs

LECTURE SLIDE DECK

Intro

You've already built two important pieces of a real application: a React + Vite frontend that users can see and interact with, and a PostgreSQL database in Supabase that stores your data. But right now, those two pieces can't talk to each other. There's a gap between them — and that gap is where APIs live.

By the end of this lecture, you'll understand what a RESTful API is, why it exists, and how to use one. You'll interact directly with real API endpoints that Supabase has already generated for your users and tasks tables — no code required yet. The goal is to build a mental model for how data moves between a UI and a database before you start writing application logic.


Lesson

What is a RESTful API?

An API (Application Programming Interface) is a defined way for two pieces of software to communicate. When developers say "API" in the context of web development, they almost always mean a web API — a system that accepts HTTP requests and returns data (usually JSON).

REST stands for Representational State Transfer. It's not a technology or a library — it's a set of architectural conventions for designing web APIs. An API that follows these conventions is called a RESTful API.

The key conventions you need to know right now are:

  • Resources are identified by URLs (e.g., /users, /tasks, /pokemon, /students, /books) and are usually pluralized nouns
  • You interact with those resources using standard HTTP methods (GET, POST, PUT, PATCH, DELETE)
  • Data is typically exchanged in JSON format (i.e. an JavaScript object or a Python dictionary)
  • Each request is stateless — the server doesn't remember anything about previous requests; every request must contain all the information needed to process it

What Does a RESTful API Do?

A RESTful API acts as a contract and a gatekeeper between your UI and your database. Neither the frontend nor the database talks directly to the other — the API sits in between.

api

This separation exists for good reasons:

  • Security — The API can verify that a user is allowed to do what they're asking before touching the database
  • Consistency — Any client (your React app, a mobile app, a third-party integration) uses the same API, getting the same data in the same format
  • Control — You decide exactly what data is exposed and how it can be modified; the raw database is never directly accessible to the outside world

In Supabase's case, they've built a RESTful API layer called PostgREST that automatically generates endpoints for every table in your database. You don't have to write the API yourself — it's already there. But understanding what it's doing is essential before you start building your own logic on top of it.

our-api


What is CRUD?

Almost every interaction with a database falls into one of four categories. The industry uses the acronym CRUD to describe them:

Letter Operation HTTP Method SQL Equivalent
C Create POST INSERT
R Read GET SELECT
U Update PATCH / PUT UPDATE
D Delete DELETE DELETE

These four operations map directly to the HTTP methods you'll use when making requests to a RESTful API. Let's look at each one.


Create — POST — Requires a Payload

A POST request is used to create a new resource. When you create a new user or add a new task, you're sending a POST request.

POST requests require a payload — a body of data attached to the request that tells the server what to create. This payload is almost always formatted as JSON.

Example: Creating a new task

POST /tasks
Content-Type: application/json

{
  "title": "Finish the API lecture",
  "is_complete": false,
  "user_id": 1
}

The server receives this, validates it, and inserts a new row into the tasks table. It typically responds with the newly created record (including its generated id) and a 201 Created status code.

What happens without a payload? The server has nothing to insert. You'll get an error — usually a 400 Bad Request.


Read — GET

A GET request is used to retrieve data. It does not modify anything on the server. GET requests have no body — all information is passed through the URL.

Fetch all tasks:

GET /tasks

Fetch a specific task by ID:

GET /tasks?id=eq.3

Fetch only incomplete tasks:

GET /tasks?is_complete=eq.false

Supabase's PostgREST API uses a query parameter syntax to let you filter, sort, and limit results directly through the URL — no custom code needed.

A successful GET request returns a 200 OK status along with the matching data as a JSON array.


Update — PATCH / PUT — Requires a Payload

Both PATCH and PUT modify an existing resource, and both require a payload describing what to change.

PATCH — modifies only the fields you include in the payload. Fields you leave out are untouched.

PATCH /tasks?id=eq.3
Content-Type: application/json

{
  "is_complete": true
}

Only is_complete is updated. Everything else on that task record stays the same.

PUT — replaces the entire resource with what you send. Fields you leave out may be set to null or their default values.

PUT /tasks?id=eq.3
Content-Type: application/json

{
  "title": "Finish the API lecture",
  "is_complete": true,
  "user_id": 1
}
When to Choose PUT Over PATCH

Use PATCH the vast majority of the time. It's safer because it only changes what you explicitly send — there's no risk of accidentally wiping out fields you didn't include.

Use PUT when you intentionally want to replace an entire record — for example, in a form where the user has edited every field and you want to guarantee the database row matches exactly what the user submitted.

A good rule of thumb: if in doubt, use PATCH.


Delete — DELETE

A DELETE request removes a resource. Like GET, it typically has no body — you identify the target through the URL.

DELETE /tasks?id=eq.3

This removes the task with ID 3. A successful response is usually 204 No Content — the server confirms the action succeeded but has nothing to return.

Be careful with DELETE requests that lack filters. A request like DELETE /tasks with no query parameters could delete every row in the table. Supabase has protections against this by default, but it's important to always be explicit about what you're targeting.


Interacting with Supabase via Postman

Now that you understand the theory, you're going to apply it hands-on. You'll use Postman to send real HTTP requests to your Supabase database's auto-generated API.


What is Postman?

Postman is a desktop and web application that lets you construct and send HTTP requests without writing any code. It's one of the most widely used tools in professional software development for testing and exploring APIs.

Think of it as a browser for APIs — instead of navigating to a webpage, you're crafting a specific HTTP request (choosing the method, URL, headers, and body) and seeing exactly what comes back.

Postman is useful at every stage of development: - Learning — Explore what an API does before writing any code - Testing — Verify that your API behaves correctly for both good and bad inputs - Debugging — Isolate whether a bug is in your frontend or your backend

Download it at postman.com if you haven't already.


Finding Your Supabase Endpoints

Supabase exposes your database through a RESTful API automatically. Here's how to find your endpoint URLs and credentials:

  1. Open your project in the Supabase Dashboard
  2. In the left sidebar, click Integrations >> Data API
  3. You'll the Project URL — This is your API base URL, formatted like: https://<your-project-id>.supabase.co/rest/v1 and your Docs which will explain your API.
  4. Finally you'll need your project API Keys to add to your headers, go to your project settings and click on API Keys to get your Publishable key

For this exercise, we'll use the Publishable key.

Lets try it out by sending a couple of requests to a few resources:

https://<your-project-id>.supabase.co/rest/v1/users
https://<your-project-id>.supabase.co/rest/v1/tasks

Required Headers for every Supabase request:

Header Value
apikey Your publishable key
Authorization Bearer <your-publishable-key>
Content-Type application/json (required for POST/PATCH/PUT)

You can save these as a Postman Environment or Collection Variables so you don't retype them on every request.


Sending Requests to Supabase

Work through each of the following requests in Postman. For each one, observe: - The status code in the response (200, 201, 204, 400, etc.) - The response body (what data came back, or what error message appeared) - What changes (or doesn't change) in your Supabase Table Editor after each request


A Note on Status Codes

You've been seeing status codes throughout this exercise. They're a standardized way for APIs to communicate the result of a request at a glance:

Code Meaning Common Scenario
200 OK Success, data returned GET requests
201 Created Resource created successfully POST requests
204 No Content Success, no data to return DELETE, PATCH
400 Bad Request Your request was malformed Missing fields, bad JSON
401 Unauthorized Missing or invalid credentials No/wrong API key
403 Forbidden Credentials valid, action not allowed RLS policy violation
404 Not Found Resource doesn't exist Bad URL path
500 Internal Server Error Something went wrong on the server Database error

When debugging an API issue, the status code is always your first clue.


The API Life Cycle Visualized

Here's a visual example of the API life cycle

api_cycle


Conclusion

You've now seen the full picture of how a frontend, an API, and a database work together. The RESTful API is the bridge — it gives your UI a structured, predictable way to read and modify data without ever touching the database directly.

The four CRUD operations (Create, Read, Update, Delete) map directly to HTTP methods (POST, GET, PATCH/PUT, DELETE), and those HTTP methods are the vocabulary your frontend will use to communicate with every backend you'll ever work with.

In the next steps, you'll connect your React frontend to these same Supabase endpoints — so instead of Postman sending the requests, your UI will. The mental model you've built today is exactly what you need to make that connection.