What Is an API
API stands for Application Programming Interface (Application Programming Interface). It sounds complicated, but the idea is simple: it's a standardized way for one program to request things from another program. Your site asks, "give me today's weather," and another service responds, without your site needing to know how that information was calculated.
🧠 Analogy: The Menu and the Restaurant Waiter
Imagine you’re at a restaurant. You don’t go into the kitchen to cook. You look at the menu (the list of things you can request), call the waiter (makes the request) and gets the finished dish. The kitchen stays hidden.
- •The menu = the API documentation (what you can request)
- •The request to the waiter = the request (you ask for something)
- •The dish that arrives = the response (usually in JSON)
- •The hidden kitchen = the server (you don't need to know how it works)
💡 You already use APIs without realizing it
When a site shows “Sign in with Google,” it’s talking to the Google API. When an app shows a map, it’s using the Google Maps API. When you see the dollar exchange rate updated, there’s an API behind it. APIs are how internet services communicate with each other.
The verbs: GET, POST, PUT, DELETE
Every request has a verb that describes the intent of the request. There are four main ones, each corresponding to an everyday action: read, create, update, and delete. Anyone who has worked with databases knows this as CRUD (Create, Read, Update, Delete).
GET
read
Looks up information without changing anything. It’s the most common verb.
Ex: “give me the list of users”.
POST
create
Sends new data to create something.
Ex: “add this new user”.
PUT
update
Changes something that already exists.
Ex: “change this user’s email”.
DELETE
delete
Removes something.
Ex: “delete this user”.
🧠 Analogy: An Address Book
Think of a contacts list on your phone. GET and opening and reading a contact. POST and adding a new contact. PUT is to edit the phone number of an existing contact. DELETE and deleting the contact. Those are the four things you do with any list of data.
💡 Tip: GET doesn't change anything
A golden rule: one GET must never change data. It only reads. If you need to create, update, or delete something, use POST, PUT, or DELETE. This prevents a simple click on “refresh page” from causing damage to the server.
Testing APIs: curl, Thunder Client, and Postman
Before writing a line of code on your site, it’s a good idea to test the API to see what it responds with. You have three options: the curl (in the terminal), Thunder Client (a VS Code extension), and Postman (an application). All three do the same thing: send a request and show the response.
curl - test from the terminal
curl comes preinstalled on Mac, Linux, and modern Windows. Just type the API URL:
# Simple GET request
$ curl https://api.exemplo.com/usuarios/1
# The API responds with JSON:
{"id": 1, "nome": "Ana", "email": "ana@email.com"}
curl with POST and a nicely formatted response
# Send data with POST (-X sets the verb, -d sends the body)
$ curl -X POST https://api.exemplo.com/usuarios \
-H "Content-Type: application/json" \
-d '{"nome": "Bia", "email": "bia@email.com"}'
{"id": 2, "nome": "Bia", "email": "bia@email.com"}
# Make the JSON readable by piping it through jq
$ curl https://api.exemplo.com/usuarios/1 | jq
{
"id": 1,
"name": "Ana",
"email": "ana@email.com"
}
👁 What you’ll see in Thunder Client
Thunder Client is a free VS Code extension. The screen has three parts:
- •At the top: a field to choose the verb (GET, POST...) and paste the URL, with a button Send.
- •In the middle: tabs for Headers, Body, and Auth (when the API requires a password or token).
- •Below: the response in colored JSON and the status (e.g., 200 OK) with the time it took.
✓ What TO DO
- ✓Test the API before adding it to the code
- ✓Save the requests you use often
- ✓Use
jqto read large JSON
✗ What NOT to do
- ✗Pasting secret tokens into public screenshots
- ✗Test DELETE directly on the production API
- ✗Ignore the response status code
Connecting the Frontend to the Supabase API
Now let’s leave the terminal and make the same request from inside your site, with JavaScript. The tool for that is fetch, which is built into the browser. In the previous module, you created a database in Supabase. It exposes an automatic REST API, so you can fetch your data directly from the frontend.
Build the URL and headers
Supabase provides a project URL and a public key (anon key). They go in the request.
// Data shown in the Supabase dashboard
const URL = "https://seu-projeto.supabase.co";
const CHAVE = "sua-chave-publica-anon";
Make the GET request with fetch
Looks up all the rows in the "tarefas" table. The await wait for the response to arrive.
const resposta = await fetch(
URL + "/rest/v1/tarefas?select=*",
{ headers: { apikey: CHAVE } }
);
Turn the response into data
The response comes as text. The .json() converts it into an array you use on the site.
const tarefas = await resposta.json();
console.log(tarefas);
[{ id: 1, titulo: "Study APIs", feito: false }]
The complete code, all together
// Fetches tasks from Supabase and displays them on the screen
async function carregarTarefas() {
const URL = "https://seu-projeto.supabase.co";
const CHAVE = "sua-chave-publica-anon";
const r = await fetch(URL + "/rest/v1/tarefas?select=*", {
headers: { apikey: CHAVE }
});
const tarefas = await r.json();
tarefas.forEach(t => console.log(t.titulo));
}
carregarTarefas();
⚠️ Common Error
Problem: "The request comes back empty or with a CORS / permission error."
Solution: In Supabase, enable RLS (Row Level Security) policies to allow public reads of the table, and check that the project URL and anon key are correct (with no extra spaces). The anon key is safe to use in the frontend; the key service_role NEVER go in the browser.
Useful Public APIs: Weather and ZIP Codes
There are thousands of free public APIs you can use right now. Two that are very practical in Brazil: the one from weather and the one for ZIP code (ViaCEP). Let’s test both with fetch.
ViaCEP - address based on ZIP code
You pass the ZIP code in the URL and receive the full address. No key or registration needed. Great for filling out address forms.
# Testing in the terminal with curl
$ curl https://viacep.com.br/ws/01001000/json/
{
"zip code": "01001-000",
"street": "Praca da Se",
"neighborhood": "Se",
"locality": "Sao Paulo",
"uf": "SP"
}
// The same thing with fetch, on the site
const cep = "01001000";
const r = await fetch("https://viacep.com.br/ws/" + cep + "/json/");
const end = await r.json();
console.log(end.localidade); // "Sao Paulo"
Weather - forecast (Open-Meteo)
Open-Meteo is free and doesn't require a key. You pass in the latitude and longitude and get the current temperature.
# Current temperature in São Paulo
$ curl "https://api.open-meteo.com/v1/forecast?latitude=-23.55&longitude=-46.63¤t=temperature_2m"
{
"current": { "temperature_2m": 24.3 }
}
🧠 Analogy: Public APIs are open libraries
A public API is like a neighborhood library: anyone can come in, look up a book, and leave without paying. Some only ask you to sign up (get a “library card,” which is an API key) to keep track of how many requests you make per day. ViaCEP and Open-Meteo don’t even require a library card.
💡 Tip: where to find more APIs
Look for “public APIs” lists on GitHub. There are APIs for currency exchange rates, holidays, motivational quotes, movie data, Pokémon, and much more. Start with the ones that don’t require a key: it’s the fastest way to practice fetch.
Error Handling: Status and try/catch
Not every request succeeds. The internet goes down, the server fails, the ZIP code doesn't exist. That's why all code that talks to an API needs to handle errors. Two tools: read the status code from the response and wrap everything in a try/catch.
OK
Everything went well. The response came back.
Not Found
The requested resource doesn’t exist.
Server Error
It's the API's fault, not yours.
A simple rule: statuses that start with 2 are successful, with 4 are your errors (you asked the wrong way), and with 5 are server errors.
Handling errors with try/catch and status
async function buscarCep(cep) {
try {
const r = await fetch("https://viacep.com.br/ws/" + cep + "/json/");
// r.ok is true when the status is 200-299
if (!r.ok) {
throw new Error("Servidor respondeu " + r.status);
}
const dados = await r.json();
if (dados.erro) {
alert("ZIP code not found. Check the number.");
return;
}
console.log(dados.localidade);
} catch (e) {
// Goes here if the internet connection drops or the fetch fails
alert("Could not connect. Try again.");
}
}
✓ What TO DO
- ✓Check
r.okorr.status - ✓Wrap the fetch in a
try/catch - ✓Show a clear message to the user
✗ What NOT to do
- ✗Assume the response will always arrive
- ✗Show raw technical errors to the user
- ✗Leave the screen stuck waiting forever
⚠️ Common Error
Problem: "The fetch didn’t hit the catch, but the site broke."
Solution: O fetch only goes to catch when the connection fails. A 404 or 500 status is considered a valid response by fetch. That’s why you MUST check r.ok manually, as in the example above. Without this, you try to read JSON that doesn't exist and the site breaks.
📚 Module Summary
Next Module:
2.4 - Environment Variables (securely store keys and secrets outside your code)