JavaScript Core/
Lesson

You already know how to make a GET request with fetch. But apps don't just read data, they create, update, and delete it too. HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. defines a small vocabulary of verbs (called methods) that tell the server what you want to do with a resource.

GET, read data

GET is the default method and is used to retrieve data. It should be safe and idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe.: calling GET a thousand times should not change anything on the server.

// No options needed - GET is the default
const response = await fetch('https://api.example.com/users');
const users = await response.json();

GET requests should never have a body. If you need to filter or paginate, use query parameters instead.

AI pitfall
AI tools sometimes generate GET requests with a body property. This is wrong, the HTTP spec says GET requests should not include a body, and many servers and browsers will ignore or reject it. If Copilot gives you fetch(url, { method: 'GET', body: JSON.stringify(filters) }), refactor the filters into query parameters instead.
02

POST, create a resource

POST is used to create something new. Unlike GET, it sends data in a request body. POST is not idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe., sending the same POST request twice typically creates two separate records.

const newUser = {
  name: 'Alice',
  email: 'alice@example.com'
};

const response = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(newUser)
});

const createdUser = await response.json();
console.log('Created with ID:', createdUser.id);
03

PUT vs PATCH, two kinds of update

This is where most people get confused. Both methods update existing data, but they work differently.

PUT replaces the entire resource. If you omit a field, it gets deleted or reset to its default. Think of it like overwriting a file, you hand the server the complete new version.

// PUT: you must send ALL fields
const updatedUser = {
  id: 1,
  name: 'Alice Smith',
  email: 'alice.smith@example.com',
  age: 31  // Every field must be present
};

await fetch('https://api.example.com/users/1', {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(updatedUser)
});

PATCH updates only what you send. Fields you omit are left untouched. Use this when you only want to change one or two things.

// PATCH: only send what changed
await fetch('https://api.example.com/users/1', {
  method: 'PATCH',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'new.email@example.com' })
});
Real-world note
Not all APIs implement PUT and PATCH correctly. Some treat them interchangeably. Always check the API docs for the specific service you're integrating with.
04

DELETE, remove a resource

DELETE removes a resource. It's idempotentWhat is idempotent?An operation that produces the same result whether you perform it once or multiple times, making retries safe.: deleting something that no longer exists should ideally return a 404 (or still a 200/204 on some APIs), but the end state is the same, the resource is gone.

const response = await fetch('https://api.example.com/users/1', {
  method: 'DELETE'
});

if (response.ok) {
  console.log('User deleted successfully');
}

DELETE requests usually don't need a body or Content-Type header.

05

Choosing the right method

OperationHTTP methodIdempotent?Sends body?Example
Read dataGETYesNoList all users
Create resourcePOSTNoYesCreate a new post
Replace resourcePUTYesYesUpdate full user profile
Partial updatePATCHNo (usually)YesChange only email
Delete resourceDELETEYesRarelyRemove a comment
06

Content-Type and sending form data

When you send data in a request body, the server needs to know how to interpret it. That's the job of the Content-Type header.

// Sending JSON
headers: { 'Content-Type': 'application/json' }

// Sending URL-encoded form data (like a traditional HTML form)
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }

// Sending a file upload - do NOT set Content-Type manually
const formData = new FormData();
formData.append('file', fileInput.files[0]);

await fetch('/upload', {
  method: 'POST',
  body: formData  // Browser sets the correct multipart Content-Type with boundary
});
07

Quick reference

OperationHTTP methodIdempotent?Sends body?
Read dataGETYesNo
Create resourcePOSTNoYes
Replace resourcePUTYesYes
Partial updatePATCHNo (usually)Yes
Delete resourceDELETEYesRarely