HTTP methods and status codes in Rails APIs
Fast recall
Quick revision
Core answer
Whether the learner can design a truthful HTTP contract rather than returning 200 for every result.
Confusing authentication 401 with authorization 403 or returning a response body with 204.
Explain safety, idempotency, validation errors, and created-resource location.
Interview-ready guide
Interview answer
HTTP methods describe the intended operation. GET retrieves a representation and should not change business state. POST commonly creates a resource or starts non-idempotent processing. PUT replaces a resource representation, PATCH applies a partial update, and DELETE requests removal.
Status codes describe what happened, not which controller action ran. A successful read is commonly 200, a newly created resource is 201, and a successful operation with no response representation can be 204. A missing resource is 404, while invalid submitted fields commonly produce 422 with machine-readable error details.
For example, POST /articles can return the created JSON with status: :created and a Location header pointing to /articles/42. If validation fails, the same action returns the model errors with :unprocessable_content instead of hiding failure behind 200.
Authentication and authorization have different failures. Missing, expired, or invalid credentials normally produce 401; an authenticated user who is not allowed to perform the operation gets 403. A malformed request may be 400, while an unexpected server failure belongs in the 5xx range and should be logged without leaking internals.
I keep the contract consistent across endpoints and test method, path, status, headers, and body together. Correct codes make clients simpler, improve monitoring, and let caches and intermediaries apply HTTP semantics instead of reverse-engineering a custom success field. The response body can add detail, but it should never contradict the status line.
HTTP methods and status codes in Rails APIs
Direct Answer
A Rails API should match HTTP methods to resource semantics—GET reads, POST creates or triggers processing, PUT/PATCH updates, and DELETE removes—and return a status that describes the outcome. Rails symbols such as :created, :no_content, :unprocessable_content, :unauthorized, and :forbidden map to standard HTTP codes.
Deep Dive & Architecture
A safe method is intended only to retrieve or inspect state. GET and HEAD are safe, so links, crawlers, prefetching, and caches may issue them without expecting a mutation. An endpoint that deletes a record on GET violates that contract even if the controller code works, because infrastructure and user agents are allowed to treat GET as observation.
Idempotent means repeating the same request has the same intended effect as making it once. PUT and DELETE are defined as idempotent, although each request may still create logs or update metrics. POST is not generally idempotent. Payment or job-start endpoints often add an idempotency key so a client can retry after a timeout without creating duplicate business work.
For creation, 201 says a new resource exists. Rails can render the representation and set location: article_url(article). A 202 response instead means processing was accepted but is not finished, which is appropriate when a background job owns completion. A 204 response means there is no content and Rails will drop a body supplied with a non-content status, so use 200 when the client needs an updated representation.
Client errors should remain specific without exposing sensitive data. A malformed JSON document can be 400. Failed authentication is 401, often with a WWW-Authenticate challenge. Refused permission is 403. A route or visible resource that does not exist is 404. Semantic validation errors can use 422 and a stable structure such as { errors: [{ field, code, message }] }.
The final design must be documented and tested as a contract. Request specs should assert allowed methods, exact status, important headers, and body shape for success and failure. Monitoring should group meaningful status families, while exception handling converts expected domain failures without turning programming defects into misleading 4xx responses.
Retries make these semantics practical. A client that loses a response needs to know whether repeating the operation is safe, idempotent, or protected by an idempotency key. Document that behaviour beside the status contract instead of leaving each client to guess.
Code Example
class Api::ArticlesController < ActionController::API
def create
article = Article.new(article_params)
if article.save
render json: article, status: :created, location: api_article_url(article)
else
render json: { errors: article.errors.to_hash }, status: :unprocessable_content
end
end
private
def article_params
params.expect(article: [:title, :body])
end
end
The success response identifies the new resource; validation failure remains a distinct client-visible outcome.
Common Mistakes & Pitfalls
Confusing authentication 401 with authorization 403 or returning a response body with 204.
Check your understanding
Answer these without looking back at the article.
- What is the difference between safe and idempotent HTTP methods?
- When should an endpoint return 202 Accepted?
- Why must a 204 response have no body?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.