Skip to content

REST API Design Interview Questions for Full Stack with Node.js

24 REST API Design questions with answers for full stack with node.js roles — 6 easy, 12 medium, 6 hard.

About REST API Design

Design clean, predictable APIs: resource URLs, HTTP methods, status codes, pagination, filtering, versioning, idempotency, error formats and caching with ETags. Learn OpenAPI documentation, webhooks with signatures, async job APIs and how REST compares with GraphQL. Good API design is a core skill tested in backend interviews and machine coding rounds.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is a REST API and what are its key constraints?

Save to ▾
Show answer
REST is an architectural style where resources are identified by URLs and manipulated through standard HTTP methods. Key constraints: client-server separation, statelessness so each request carries all needed information, cacheable responses, uniform interface, layered system and optionally code on demand. In practice it means resource-based URLs, correct methods and status codes, and JSON representations.
02

Explain the main HTTP methods and which are idempotent.

Save to ▾
Show answer
GET reads a resource, POST creates or triggers an action, PUT replaces a resource fully, PATCH updates part of it and DELETE removes it. GET, PUT, DELETE, HEAD and OPTIONS are idempotent, meaning repeating the request has the same effect as doing it once. POST and usually PATCH are not, which is why payment APIs use idempotency keys for POST.
03

Which HTTP status codes should a REST API commonly return?

Save to ▾
Show answer
200 OK for successful reads and updates, 201 Created with a Location header for new resources, 204 No Content for deletes. 400 for invalid input, 401 when not authenticated, 403 when authenticated but not allowed, 404 not found, 409 conflict such as a duplicate email, 422 for validation errors in some APIs, 429 rate limited, 500 server error and 503 unavailable.
04

What is the difference between PUT and PATCH?

Save to ▾
Show answer
PUT replaces the entire resource with the representation sent, so missing fields may be reset; it is idempotent. PATCH applies a partial update, sending only changed fields, such as { "phone": "..." }. PATCH is more efficient for large objects. With JSON Merge Patch, repeated identical PATCH requests are effectively idempotent, but operations like increment are not.
05

How do you design good REST endpoint URLs?

Save to ▾
Show answer
Use plural nouns for resources and let methods express the action: GET /users, POST /users, GET /users/42, PATCH /users/42. Nest only for clear ownership, like GET /users/42/orders, and avoid deep nesting. Use lowercase kebab-case, query parameters for filtering, sorting and pagination, and version the API, for example /api/v1. Avoid verbs like /getUsers.
06

How do you document a REST API?

Save to ▾
Show answer
Use the OpenAPI 3 specification, written by hand in YAML or generated from code or validation schemas, and serve it with Swagger UI or Redoc. Document each endpoint's parameters, request and response schemas, status codes, auth and examples. Keep it in the repo, validate it in CI and generate client SDKs or contract tests from it so docs never drift from the code.
07

Compare offset pagination and cursor pagination.

Save to ▾
Show answer
Offset pagination uses page and limit, translated to LIMIT and OFFSET. It is simple and allows jumping to a page, but gets slow on large tables and can skip or repeat rows when data changes. Cursor pagination uses the last seen value, such as id or created_at, to fetch the next set with a WHERE clause. It is fast and stable, ideal for feeds and infinite scroll.
08

Implement cursor-based pagination for a products endpoint.

Save to ▾
Show answer
router.get('/products', async (req, res) => { const limit = Math.min(Number(req.query.limit) || 20, 100); const cursor = req.query.cursor; const filter = cursor ? { _id: { $lt: cursor } } : {}; const items = await Product.find(filter) .sort({ _id: -1 }) .limit(limit + 1); const hasMore = items.length > limit; if (hasMore) items.pop(); res.json({ data: items, nextCursor: hasMore ? items[items.length - 1]._id : null }); });
09

What are the common strategies for API versioning?

Save to ▾
Show answer
URL versioning like /api/v1/orders is the most common and easy to route and cache. Header versioning uses a custom header or Accept media type, keeping URLs clean but less visible. Query versioning like ?version=2 is simple but messy. Whatever you choose, version only for breaking changes, support old versions for a deprecation period and announce sunset dates.
10

How do you design a consistent error response format for an API?

Save to ▾
Show answer
Use one structure everywhere, for example { "error": { "code": "VALIDATION_FAILED", "message": "Email is invalid", "details": [{ "field": "email" }], "requestId": "abc123" } }. Many teams follow RFC 9457 Problem Details with type, title, status and detail. Use machine-readable codes for clients, human messages for display, and never leak stack traces or SQL errors.
11

What is the difference between REST and GraphQL?

Save to ▾
Show answer
REST exposes multiple endpoints with fixed response shapes, uses HTTP caching easily and is simple to reason about. GraphQL exposes one endpoint where clients query exactly the fields they need, reducing over-fetching and multiple round trips, which helps mobile apps. GraphQL adds complexity: N+1 query risks needing DataLoader, harder caching, query cost limits and schema governance.
12

How do you implement filtering and sorting safely from query parameters?

Save to ▾
Show answer
const ALLOWED_SORT = ['price', 'createdAt', 'name']; router.get('/products', async (req, res) => { const filter = {}; if (req.query.category) filter.category = String(req.query.category); if (req.query.maxPrice) filter.price = { $lte: Number(req.query.maxPrice) }; const field = ALLOWED_SORT.includes(req.query.sort) ? req.query.sort : 'createdAt'; const dir = req.query.order === 'asc' ? 1 : -1; res.json(await Product.find(filter).sort({ [field]: dir }).limit(50)); }); // Whitelist fields and cast types to block injection.
13

Design endpoints for a simple e-commerce cart and checkout.

Save to ▾
Show answer
GET /api/v1/cart returns the current user's cart. POST /api/v1/cart/items adds an item with productId and quantity. PATCH /api/v1/cart/items/:itemId changes quantity, and DELETE removes it. POST /api/v1/orders creates an order from the cart with an Idempotency-Key header. GET /api/v1/orders/:id shows status, and POST /api/v1/orders/:id/cancel handles cancellation as an action.
14

A mobile app team complains your API returns too much data and is slow on 4G. What would you change?

Save to ▾
Show answer
Add field selection like ?fields=id,name,price, smaller list representations with details on a separate endpoint, pagination with sensible limits and gzip or Brotli compression. Support ETag and Cache-Control so unchanged data returns 304. If many screens need combined data, consider a Backend-for-Frontend layer or GraphQL tailored to the mobile app.
15

You must change a response field name used by many clients. How do you do it without breaking them?

Save to ▾
Show answer
Treat it as a breaking change. Option one: add the new field alongside the old one, mark the old field deprecated in docs and response headers, track usage through logs and remove it after clients migrate. Option two: release it in /v2 and keep /v1 for a deprecation window. Communicate timelines clearly and add contract tests for both.
16

How does HTTP caching with ETag and Cache-Control work for APIs?

Save to ▾
Show answer
Cache-Control tells clients and CDNs how long a response is fresh, for example public, max-age=300, or private, no-store for user data. An ETag is a hash of the response; the client sends it back in If-None-Match, and if nothing changed the server returns 304 Not Modified with no body. Express generates weak ETags automatically for res.send responses.
17

How do you handle a breaking API change request from a product manager close to a release?

Save to ▾
Show answer
I would first understand why it is needed and who consumes the API. Then I explain the impact on existing clients, propose a non-breaking path such as adding a new field or a v2 endpoint, and estimate effort and risk. Result in a past case: we shipped the additive change on time and scheduled removal of the old field for the next quarter.
18

Tell me about an API you designed that you are proud of.

Save to ▾
Show answer
Situation: our support team used spreadsheets to track refunds. Task: I designed a refund API used by the admin panel and payment service. Action: I wrote the OpenAPI spec first, reviewed it with frontend and finance, added idempotency keys, clear error codes and pagination, and wrote contract tests. Result: integration took two days instead of a week, and refund errors dropped sharply.
19

What is idempotency and how do you implement idempotency keys for a payment API?

Save to ▾
Show answer
An idempotent operation gives the same result when repeated. For POST /payments, the client sends a unique Idempotency-Key header. The server stores the key with the request hash and response, for example in Redis or a table with a unique index. If the same key arrives again, it returns the saved response instead of charging twice. Keys expire after about 24 hours.
20

What is HATEOAS and is it used in real projects?

Save to ▾
Show answer
HATEOAS, Hypermedia as the Engine of Application State, means responses include links telling the client what it can do next, for example an order response with links to cancel or pay. It makes APIs more discoverable and decoupled. In practice most JSON APIs only partly use it, such as pagination links, because clients are usually built against documented endpoints.
21

How would you design an API for a long-running task such as exporting a 1 GB report?

Save to ▾
Show answer
Do not keep the HTTP request open. POST /exports creates a job, pushes it to a queue and returns 202 Accepted with a job ID and status URL. Clients poll GET /exports/:id or receive a webhook or WebSocket event. A worker generates the file, uploads it to object storage, and the status endpoint returns a short-lived signed download URL.
22

How do you implement and secure webhooks that your API sends to customers?

Save to ▾
Show answer
Send a POST with a JSON event, a unique event ID and timestamp. Sign the body with HMAC-SHA256 using a per-customer secret and include it in a header, so receivers verify authenticity and reject old timestamps to stop replays. Retry failures with exponential backoff, log delivery attempts and make events idempotent so receivers can safely handle duplicates.
23

Write code to verify an HMAC signature on an incoming webhook in Express.

Save to ▾
Show answer
const crypto = require('crypto'); app.post('/webhooks/payment', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.get('X-Signature') || ''; const expected = crypto .createHmac('sha256', process.env.WEBHOOK_SECRET) .update(req.body) .digest('hex'); const ok = sig.length === expected.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)); if (!ok) return res.status(401).end(); handleEvent(JSON.parse(req.body)); res.status(200).end(); });
24

A partner integration retries POST requests on timeouts and creates duplicate orders in your API. How would you redesign the endpoint?

Save to ▾
Show answer
Require an Idempotency-Key header on order creation and store it with a unique index alongside the created order ID and response. On a repeated key with the same payload, return the original response; with a different payload, return 409 or 422. Also add a unique business constraint such as partner order reference, respond quickly by queueing slow work, and document retry behaviour for partners.

Frequently asked questions

How important is REST API Design in Full Stack with Node.js interviews?

Design clean, predictable APIs: resource URLs, HTTP methods, status codes, pagination, filtering, versioning, idempotency, error formats and caching with ETags. Learn OpenAPI documentation, webhooks with signatures, async job APIs and how REST compares with GraphQL. Good API design is a core skill tested in backend interviews and machine coding rounds.

How should I use the REST API Design sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.