Quiz
Click "Answer" to reveal the correct answer and explanation.
REST API Design
Q1. Which HTTP method is idempotent but not safe?
- A.
GETβ safe and idempotent - B.
POSTβ neither safe nor idempotent - C.
PUTβ calling it multiple times with the same body produces the same result, but it modifies server state - D.
DELETEβ safe because it only removes data
Answer
C β PUT.
Safe means the request does not modify server state. Idempotent means calling it multiple times has the same effect as calling it once. PUT /orders/42 with the same body can be retried freely β the result is the same order state regardless of how many times it is called, but the first call did change state, so it is not safe. POST /orders would create a new order on each call (not idempotent).
Q2. A client receives 401 Unauthorized. What does this specifically indicate?
- A. The user is authenticated but lacks the required role or permission
- B. No valid authentication token was provided, or the token is invalid or expired
- C. The requested resource does not exist on the server
- D. The server encountered an unexpected error processing the request
Answer
B β No valid authentication token.
401 means "you are not authenticated" β the server does not know who you are. 403 Forbidden means "I know who you are, but you are not allowed to do this." Confusing the two is a common mistake: a missing JWT should return 401, not 403.
Q3. Which URI designs follow REST conventions?
- A.
POST /createOrderandGET /getOrderById?id=42 - B.
GET /ordersandGET /orders/42 - C.
GET /order-listandDELETE /removeOrder/42 - D.
POST /orders/createandPUT /orders/update/42
Answer
B β GET /orders and GET /orders/42.
REST URIs identify resources (nouns), not operations (verbs). Use plural nouns for collections (/orders), nest for hierarchy (/orders/42), and express the operation through the HTTP method (GET, POST, PUT, DELETE) β never in the path.
Q4. What is the correct HTTP status code when a POST successfully creates a new resource?
- A.
200 OKβ success is always 200 - B.
201 Created, accompanied by aLocationheader pointing to the new resource's URI - C.
202 Acceptedβ creation is queued for asynchronous processing - D.
204 No Contentβ used when the server has nothing to return
Answer
B β 201 Created with Location header.
200 is for successful reads and updates. 201 signals that a new resource was created and tells the client where to find it via Location: /orders/42. This allows the client to immediately navigate to or cache the new resource without a separate GET.
Q5. Why is cursor-based pagination preferred over offset pagination for large datasets?
- A. Cursors are smaller in size than page numbers, reducing request payload
- B. Offset pagination is not supported by the HTTP specification
- C. Offset pagination requires the database to skip rows, which is expensive at scale and causes drift when items are inserted or deleted; cursor pagination reads forward from a stable pointer
- D. Cursor pagination allows the client to jump to any page directly
Answer
C β Offset is expensive and drift-prone; cursor reads from a stable pointer.
OFFSET 10000 LIMIT 20 forces the database to count and skip 10,000 rows β slow on large tables. If a new item is inserted on page 3 while the client reads page 4, rows shift and the client sees duplicates or skips items. A cursor (e.g., after=eyJpZCI6NDJ9) encodes the last-seen record and reads forward from exactly that point (WHERE id > :last), using the index and immune to insertions. Option D is wrong: jumping to an arbitrary page is what cursors cannot do.
Q6. Which level of the Richardson Maturity Model describes correct use of HTTP verbs and status codes?
- A. Level 0 β Swamp of POX (single endpoint for all operations)
- B. Level 1 β Resources (separate URIs per resource)
- C. Level 2 β HTTP Verbs (correct methods + status codes)
- D. Level 3 β HATEOAS (responses include links to next actions)
Answer
C β Level 2.
Level 2 adds semantic use of HTTP methods (GET to read, POST to create, DELETE to remove) and proper status codes (201 Created, 404 Not Found, 409 Conflict). Most production REST APIs operate at Level 2. Level 3 (HATEOAS) adds hypermedia links and is rare in practice.
Q7. A client calls DELETE /products/42 and gets 204. The response to a retry of the same request is 404 Not Found. Is DELETE still idempotent?
- A. No β idempotent requests must always return the same response
- B. Yes β idempotency is about the effect on server state: after one call or many, product 42 does not exist
- C. No β the server should have returned
204again to be idempotent - D. Only if the client sends an
Idempotency-Keyheader
Answer
B β Idempotency is about the state, not the response.
RFC 9110 defines idempotent methods by their intended effect on the server. The second DELETE finds nothing to delete, so 404 is a correct answer and the state is unchanged. A client that retries a DELETE should treat 404 as success.
Q8. A mobile app sends POST /orders, the connection drops, and the app does not know whether the order was created. Which design lets it retry without creating a duplicate order?
- A. Switch the endpoint to
GET /orders/create, sinceGETis idempotent - B. Retry immediately, as many times as needed, until a response arrives
- C. Send a client-generated
Idempotency-Keyheader; the server stores processed keys and returns the stored result when a key repeats - D. Return
202 Acceptedinstead of201 Created
Answer
C β Idempotency key.
The key identifies the logical operation. The first request creates the order and records the key; the retry finds the key and returns the same order instead of creating another. Option A breaks HTTP semantics (GET must not change state), B creates duplicates, and D changes the status code but not the duplication problem.
Q9. The product service is consumed by the web front-end and the order service. Which change is breaking and therefore needs a new API version?
- A. Adding a new optional field
descriptiontoProductIn - B. Adding a new field
categorytoProductOut - C. Adding a new endpoint
GET /products/search - D. Renaming the response field
pricetounitPrice
Answer
D β Renaming a response field.
Existing clients still read price and now get nothing. Adding endpoints, optional request fields or response fields is backward compatible as long as clients are tolerant readers that ignore unknown fields. A breaking change goes to a new version (/v2/products) with a deprecation period for /v1.
OpenAPI & Swagger
Q10. What does the springdoc-openapi library generate automatically at startup?
- A. A PDF export of all controller method signatures
- B. A Postman collection for manual API testing
- C. An OpenAPI document by introspecting controllers and model classes, and a Swagger UI served at
/swagger-ui.html - D. Unit test stubs for every endpoint declared in the codebase
Answer
C β OpenAPI document + Swagger UI at /swagger-ui.html.
springdoc-openapi reads @RestController, @GetMapping, @RequestBody, @Schema and similar annotations at application startup, generates a standards-compliant OpenAPI 3 document at /v3/api-docs, and serves an interactive Swagger UI β all without any manual YAML authoring.
Q11. Where should Swagger UI be disabled, and why?
- A. In development β developers should use
curlinstead - B. In staging β the staging environment must mirror production exactly
- C. In production β it exposes the full attack surface of the API to anyone who accesses it
- D. Only in microservices β monoliths can safely expose Swagger UI in production
Answer
C β In production.
Swagger UI provides an interactive map of every endpoint, parameter, and security scheme. An attacker can use it to enumerate attack vectors without reading the source code. Disable it with springdoc.swagger-ui.enabled: false and springdoc.api-docs.enabled: false in application-prod.yml.
Q12. What is the purpose of @Schema on a Java record field in a springdoc-openapi project?
- A. It marks the field as required for JSON deserialization
- B. It maps the field name to a different JSON key in the serialised output
- C. It adds a human-readable description and example value that appears in the generated OpenAPI document and Swagger UI
- D. It instructs the validator to reject null values for that field
Answer
C β Adds description and example to the OpenAPI document.
Without @Schema, springdoc only knows the field name and type. @Schema(description = "Unit price", example = "10.12") makes the generated documentation self-explanatory β consumers know what the field means and what a valid value looks like, without reading the source code.
Q13. To allow Swagger UI to send authenticated requests with a JWT Bearer token, what must be configured?
- A. Add
@Securedto every controller method and include the token in the request body - B. Enable Spring Security's basic auth fallback in
application.yaml - C. Add a
SecuritySchemeof typeHTTP/bearerto theOpenAPIbean, then use the Authorize button in Swagger UI to supply the token - D. Configure
springdoc.swagger-ui.oauth.client-idwith the JWT issuer URL
Answer
C β SecurityScheme of type HTTP/bearer + Authorize button.
Adding the security scheme to the OpenAPI bean tells springdoc to render an Authorize button in Swagger UI. The user pastes a JWT there, and all subsequent requests include Authorization: Bearer <token>. Without this configuration, Swagger UI sends unauthenticated requests to all secured endpoints.
Q14. In an OpenAPI 3 document, where are the reusable data models (such as ProductOut) defined, so that several responses can reference them with $ref?
- A.
info - B.
servers - C.
paths./products/{id}.get.parameters - D.
components.schemas
Answer
D β components.schemas.
paths describes the endpoints; each response points to a model with $ref: "#/components/schemas/ProductOut", so the model is defined once. info holds title and version, servers the base URLs, and parameters the path, query, header and cookie inputs of one operation. springdoc builds components.schemas from your DTO records.