Safe HTTP Methods
Fast recall
Quick revision
Core answer
GET, HEAD, OPTIONS, and TRACE. They may still cause incidental work such as access logging; safety means the client did not ask for an application-state change.Interview-ready guide
Interview answer
A safe HTTP method has essentially read-only request semantics: the client asks for information or communication options and does not ask the server to change application state. HTTP defines GET, HEAD, OPTIONS, and TRACE as safe. Safety describes the method contract, not whether the server performs absolutely no internal work.
A safe request may write an access log, update a metric, or fill a cache. Those effects happen while serving the read; they are not the business action requested by the client. Cancelling an order, charging the customer for an order, or reducing inventory is different because it changes application state on the client's behalf and must not be hidden inside GET.
Browsers can prefetch links, crawlers can follow them, and caches can retrieve them automatically. If GET /orders/42?cancel=true cancels an order, an automated reader can cause data loss simply by following a URI. The cancellation needs an unsafe operation such as POST /orders/42/cancellation or a documented state update, together with the normal authorization and retry rules.
Every safe method is also idempotent, but the reverse is not true. PUT and DELETE are idempotent by method semantics because repeating them has the same intended effect, yet they are not safe because they request a change. TRACE is standardized as safe but is often disabled; a method can be safe by semantics without every server choosing to support it.
Safe HTTP Methods
Direct Answer
Safe HTTP methods are methods whose defined request semantics are essentially read-only: GET, HEAD, OPTIONS, and TRACE. They may still cause incidental work such as access logging; safety means the client did not ask for an application-state change.
Deep Dive & Architecture
Safety is judged by the effect the client requests, not by the annotation or function name. A @GetMapping handler that calls cancellation logic is still an unsafe operation wearing a GET label. Logging the read is different because the client did not ask for the log entry as the result of the request.
At the HTTP boundary, keep reads and commands separate. A link or automated reader can retrieve an order with GET without changing it. Cancellation gets its own unsafe endpoint, where the API can apply authorization, validation, and any retry rule required by that command.
A useful test records the order state, calls the GET endpoint, and proves the state did not change. A separate test calls the cancellation endpoint and checks the intended transition. This tests the behavioral promise instead of trusting the annotation alone.
Code Example
@GetMapping("/orders/{id}")
OrderResponse find(@PathVariable("id") long id) {
return orders.find(id);
}
@PostMapping("/orders/{id}/cancellation")
ResponseEntity<Void> cancel(
@PathVariable("id") long id,
@Valid @RequestBody CancelOrderRequest request) {
orders.cancel(id, request.reason());
return ResponseEntity.noContent().build();
}
CancelOrderRequest is the validated request DTO that carries the cancellation reason. The GET handler only retrieves the order, while the separate POST makes the requested state change visible in the HTTP contract. The exact cancellation design can also use a documented state update; the important rule is that cancellation must not pretend to be a safe retrieval.
Check your understanding
Answer these without looking back at the article.
- Can a safe request write an access log?
- Why is DELETE idempotent but not safe?
- Why is a destructive GET dangerous even when authorization is checked?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.