NodeJSHTTP Methods

HTTP Methods

The HTTP method (or verb) declares what a request wants to do with a resource — fetch it, create one, update it, delete it. Methods are the backbone of REST API design, and two of their properties — safety and idempotency — have real consequences for retries, caching, and correctness. This page covers each method, what it means, and the rules that aren't obvious until they bite you.

Reading the method in Node

JS
import { createServer } from 'node:http'

createServer((req, res) => {
  switch (req.method) {
    case 'GET':    return handleGet(req, res)
    case 'POST':   return handlePost(req, res)
    case 'PUT':    return handlePut(req, res)
    case 'DELETE': return handleDelete(req, res)
    default:
      res.writeHead(405, { Allow: 'GET, POST, PUT, DELETE' })
      res.end('Method Not Allowed')
  }
}).listen(3000)
Respond 405 with an `Allow` header for unsupported methods
When a route exists but doesn't support the requested method, the correct response is **405 Method Not Allowed**, and you should include an `Allow` header listing the methods that *are* permitted. This is different from 404 (the resource itself doesn't exist). Clients and proxies use `Allow` to know what's possible.
The common methods

Method

Purpose

Has body?

GET

Retrieve a resource

No

POST

Create a resource / submit data

Yes

PUT

Replace a resource entirely

Yes

PATCH

Partially update a resource

Yes

DELETE

Remove a resource

Sometimes

HEAD

Like GET but headers only, no body

No

OPTIONS

Ask what methods/CORS are allowed

No

Safe vs idempotent — the two properties that matter

These two terms are constantly confused, but they're distinct and important:

  • Safe = the request does not change server state (read-only). GET, HEAD, OPTIONS are safe.

  • Idempotent = making the request N times has the same effect as making it once. GET, PUT, DELETE, HEAD are idempotent.

  • POST is neither safe nor idempotent — two POSTs typically create two resources.

  • PATCH is generally not guaranteed idempotent (depends on the patch semantics).

Method

Safe?

Idempotent?

GET / HEAD

Yes

Yes

PUT

No

Yes

DELETE

No

Yes

POST

No

No

PATCH

No

Not necessarily

Idempotency governs whether a request is safe to retry
When a request times out, the client doesn't know if it succeeded. Retrying an **idempotent** method (PUT, DELETE, GET) is safe — the end state is the same. Retrying a **non-idempotent** POST risks creating duplicates (two orders, two charges). This is why payment and "create" endpoints often require an **idempotency key**: a client-supplied token the server uses to dedupe retries of the same logical operation.
PUT vs PATCH

Both update, but differently. PUT replaces the whole resource with the body you send; PATCH applies a partial change. Sending a PUT with only some fields can wipe the omitted ones:

Text
Resource:  { "name": "Ada", "email": "ada@x.com", "role": "admin" }

PUT /users/1   { "name": "Ada Lovelace" }
→ replaces entirely → { "name": "Ada Lovelace" }   ← email & role GONE

PATCH /users/1 { "name": "Ada Lovelace" }
→ merges → { "name": "Ada Lovelace", "email": "ada@x.com", "role": "admin" }
A `PUT` with a partial body can delete fields
Because `PUT` means "make the resource exactly this," omitting fields can erase them — a real source of data-loss bugs when developers treat PUT like a partial update. If you intend to change only some fields, use `PATCH`. If you use PUT, send the **complete** representation.
GET vs POST and bodies
GET requests should not carry a body — and many tools strip it
While the spec doesn't strictly forbid a GET body, it has no defined meaning, and proxies, caches, and HTTP libraries routinely ignore or drop it. Put parameters in the **query string** for GET. If you need to send a payload to read data (a complex search), either encode it in the query string or use POST — never rely on a GET body.
HEAD and OPTIONS
  • HEAD returns the same headers as GET (including Content-Length) but no body — useful to check if a resource exists, its size, or its Last-Modified without downloading it.

  • OPTIONS asks the server what it allows. Browsers send an automatic OPTIONS preflight before certain cross-origin requests (CORS) to check permissions.

The CORS preflight is an automatic OPTIONS request
When browser JavaScript makes a cross-origin request that isn't "simple" (e.g. a PUT, or with custom headers), the browser first sends an `OPTIONS` preflight asking "is this allowed?" Your server must answer it with the right `Access-Control-Allow-*` headers or the real request is blocked. If your API mysteriously fails only from a browser (not curl), an unhandled OPTIONS preflight is a prime suspect.
RESTful mapping

Action

Method + path

List users

GET /users

Get one user

GET /users/42

Create a user

POST /users

Replace a user

PUT /users/42

Partially update

PATCH /users/42

Delete a user

DELETE /users/42

Next
The three-digit codes that tell the client how it went: [HTTP Status Codes](/nodejs/http-status-codes).