Chapter 17 Quiz: Backend Development and REST APIs

Test your understanding of backend development concepts, REST API design, Flask, FastAPI, and related topics covered in this chapter.


Question 1

Which HTTP method is most appropriate for creating a new resource in a REST API?

  • A) GET
  • B) PUT
  • C) POST
  • D) PATCH
Show Answer **C) POST** POST is the standard HTTP method for creating new resources. GET retrieves resources, PUT replaces an entire resource (update), and PATCH partially updates a resource. POST is also the only one of these methods that is not idempotent, which aligns with creation semantics -- creating the same resource twice should result in two resources.

Question 2

What is the key difference between a 401 Unauthorized and a 403 Forbidden response?

  • A) 401 means the server is down; 403 means the resource does not exist
  • B) 401 means authentication is missing or invalid; 403 means the user is authenticated but lacks permission
  • C) 401 is for GET requests; 403 is for POST requests
  • D) They are interchangeable and mean the same thing
Show Answer **B) 401 means authentication is missing or invalid; 403 means the user is authenticated but lacks permission** A 401 response indicates that the request lacks valid authentication credentials. The client should authenticate and retry. A 403 response indicates that the server understood the request and the client's identity, but the client does not have permission to access the resource. Re-authenticating will not help.

Question 3

Which of the following URL patterns best follows REST conventions?

  • A) POST /api/users/createUser
  • B) POST /api/users
  • C) POST /api/user/new
  • D) POST /api/create-user
Show Answer **B) POST /api/users** REST conventions use plural nouns for resource collections and rely on HTTP methods (POST) rather than verbs in the URL to indicate the operation. Options A, C, and D all include verbs or action words in the URL, which violates REST naming conventions. The HTTP method POST already communicates "create."

Question 4

What does FastAPI use Pydantic models for?

  • A) Database queries only
  • B) Request/response validation, serialization, and automatic documentation
  • C) HTML template rendering
  • D) Server configuration only
Show Answer **B) Request/response validation, serialization, and automatic documentation** Pydantic models in FastAPI serve triple duty: they validate incoming request data against defined types and constraints, serialize response data to the correct format, and generate OpenAPI schema documentation automatically. This is one of FastAPI's key advantages over Flask, where validation, serialization, and documentation typically require separate libraries and manual effort.

Question 5

In Flask, what is the purpose of Blueprints?

  • A) To create database schemas
  • B) To organize related routes into reusable modules
  • C) To generate API documentation
  • D) To handle authentication
Show Answer **B) To organize related routes into reusable modules** Flask Blueprints allow you to group related routes, error handlers, and static files into separate modules that can be registered with the main application. This is essential for organizing larger applications. For example, you might have blueprints for users, products, and orders, each in their own Python module.

Question 6

What HTTP status code should be returned when a resource is successfully created?

  • A) 200 OK
  • B) 201 Created
  • C) 204 No Content
  • D) 202 Accepted
Show Answer **B) 201 Created** 201 Created is the appropriate status code for a successful POST request that results in the creation of a new resource. The response should typically include the created resource in the body and a Location header pointing to the new resource's URL. Using 200 OK for creation is technically valid but less semantically precise.

Question 7

What is the primary advantage of FastAPI's async endpoint support?

  • A) It makes code easier to read
  • B) It enables higher concurrency for I/O-bound operations
  • C) It makes code run faster on a single CPU
  • D) It eliminates the need for error handling
Show Answer **B) It enables higher concurrency for I/O-bound operations** Async endpoints allow the server to handle other requests while waiting for I/O operations (database queries, external API calls, file reads) to complete. This dramatically improves throughput for I/O-bound workloads. Async does not inherently make individual operations faster or simplify code -- in fact, async code can be more complex to reason about. The benefit is concurrency, not speed per request.

Question 8

Which of the following is NOT a REST principle?

  • A) Resources are identified by URLs
  • B) Stateless communication
  • C) Operations use standard HTTP methods
  • D) The server maintains client session state between requests
Show Answer **D) The server maintains client session state between requests** REST explicitly requires stateless communication -- each request must contain all the information needed to process it. The server does not maintain client session state between requests. While session-based authentication exists, it is technically a relaxation of the REST stateless constraint. Options A, B, and C are all core REST principles.

Question 9

What does CORS middleware do in a web API?

  • A) Encrypts all API responses
  • B) Controls which domains are allowed to make requests to your API from browsers
  • C) Compresses response bodies
  • D) Validates request parameters
Show Answer **B) Controls which domains are allowed to make requests to your API from browsers** CORS (Cross-Origin Resource Sharing) is a browser security mechanism. When a web page at `https://frontend.com` makes a request to `https://api.example.com`, the browser checks CORS headers to determine if the request is allowed. CORS middleware adds the appropriate headers (Access-Control-Allow-Origin, etc.) to responses. Without CORS configuration, browsers will block cross-origin API requests.

Question 10

In the context of JWT authentication, what is the purpose of a refresh token?

  • A) To encrypt the access token
  • B) To obtain a new access token without requiring the user to log in again
  • C) To store user preferences
  • D) To validate the user's password
Show Answer **B) To obtain a new access token without requiring the user to log in again** Access tokens are typically short-lived (15-30 minutes) for security. When an access token expires, the client uses the refresh token to obtain a new access token without forcing the user to enter their credentials again. Refresh tokens are longer-lived (days or weeks) and are stored more securely. This two-token approach balances security (short-lived access tokens) with usability (users stay logged in).

Question 11

What is the Flask application factory pattern?

  • A) A design pattern where routes are generated automatically from database models
  • B) A function (typically create_app()) that creates and configures the Flask application instance
  • C) A way to create multiple Flask applications on different ports
  • D) A pattern for generating Flask boilerplate code
Show Answer **B) A function (typically `create_app()`) that creates and configures the Flask application instance** The application factory pattern creates the Flask app inside a function rather than at module level. This supports multiple configurations (development, testing, production), avoids circular imports, and makes testing easier because each test can create a fresh application instance. It is the recommended approach for all production Flask applications.

Question 12

Which Pydantic field definition makes a field optional with a default value of None?

  • A) name: str = None
  • B) name: Optional[str] = Field(None)
  • C) name: str = Field(required=False)
  • D) name: str = Field(default=None, optional=True)
Show Answer **B) `name: Optional[str] = Field(None)`** `Optional[str]` (or `str | None` in Python 3.10+) declares that the field can be either a string or None. `Field(None)` sets the default value to None, making the field optional in requests. Option A would also work in practice (Pydantic interprets it as Optional[str]), but Option B is more explicit and includes Field for additional validation options.

Question 13

What is the purpose of middleware in a web application?

  • A) To define database schemas
  • B) To process requests and responses globally, handling cross-cutting concerns
  • C) To generate API documentation
  • D) To create HTML templates
Show Answer **B) To process requests and responses globally, handling cross-cutting concerns** Middleware intercepts every request before it reaches the endpoint handler and every response before it is sent to the client. Common uses include logging, authentication, CORS headers, rate limiting, request ID tracking, and response compression. Middleware prevents the need to duplicate this logic in every endpoint.

Question 14

An API returns this response. What type of error does it indicate?

{
    "detail": [
        {"loc": ["body", "email"], "msg": "value is not a valid email address", "type": "value_error.email"}
    ]
}
  • A) A 500 Internal Server Error
  • B) A 401 Authentication Error
  • C) A 422 Validation Error (FastAPI/Pydantic)
  • D) A 404 Not Found Error
Show Answer **C) A 422 Validation Error (FastAPI/Pydantic)** This response format is characteristic of FastAPI's automatic validation error responses. When a Pydantic model validation fails, FastAPI returns a 422 Unprocessable Entity with a "detail" array containing the location of each error ("body" > "email"), the error message, and the error type. This happens automatically without any manual error handling code.

Question 15

What is the difference between path parameters and query parameters?

  • A) Path parameters are in the URL path and identify a resource; query parameters modify the request
  • B) Path parameters are for GET requests; query parameters are for POST requests
  • C) There is no difference; they are interchangeable
  • D) Path parameters are encrypted; query parameters are not
Show Answer **A) Path parameters are in the URL path and identify a resource; query parameters modify the request** Path parameters (like `/api/books/42`) are part of the URL structure and typically identify a specific resource. Query parameters (like `?page=2&sort=title`) modify how the operation is performed -- filtering, sorting, pagination, etc. A good rule of thumb: if removing the parameter makes the URL meaningless, it should be a path parameter. If it merely changes the result set, it should be a query parameter.

Question 16

What is dependency injection in FastAPI?

  • A) A way to install Python packages automatically
  • B) A system where functions declare their dependencies as parameters and the framework provides them
  • C) A pattern for injecting SQL queries into the database
  • D) A method for loading configuration files
Show Answer **B) A system where functions declare their dependencies as parameters and the framework provides them** FastAPI's dependency injection uses `Depends()` to declare that an endpoint requires a certain dependency. The framework calls the dependency function and passes the result to the endpoint. Dependencies can have their own dependencies, forming a tree. Common uses include authentication (get_current_user), database sessions, and configuration. This pattern promotes testability and code reuse.

Question 17

Which of the following is an idempotent HTTP method?

  • A) POST
  • B) PATCH
  • C) PUT
  • D) Both B and C
Show Answer **C) PUT** An idempotent operation produces the same result regardless of how many times it is executed. PUT is idempotent because replacing a resource with the same data multiple times always results in the same state. GET and DELETE are also idempotent. POST is not idempotent because creating a resource twice typically results in two resources. PATCH is not required to be idempotent by the HTTP specification, though it can be implemented as such.

Question 18

What does the response_model parameter in a FastAPI route decorator do?

  • A) It validates the response data, filters out extra fields, and generates documentation
  • B) It only validates the request body
  • C) It defines the database model to use
  • D) It specifies the HTTP response code
Show Answer **A) It validates the response data, filters out extra fields, and generates documentation** The `response_model` parameter tells FastAPI to validate the response data against the Pydantic model, serialize it to JSON, filter out any fields not in the model (important for security -- it prevents accidentally leaking internal fields like password hashes), and include the model schema in the OpenAPI documentation. It is a powerful feature that ensures your API returns exactly what it documents.

Question 19

Why should you avoid hardcoding secret keys in source code?

  • A) It makes the code harder to read
  • B) Secrets in source code can be exposed through version control, logs, and error messages
  • C) Hardcoded values are slower to process
  • D) Python does not support string constants
Show Answer **B) Secrets in source code can be exposed through version control, logs, and error messages** Hardcoded secrets are one of the most common security vulnerabilities. Once committed to version control, secrets remain in the git history even if removed later. They can also appear in error messages, stack traces, log files, and Docker images. The correct approach is to use environment variables or a secrets management service, loaded via a configuration system like Pydantic's BaseSettings.

Question 20

What is the purpose of API versioning?

  • A) To track how many times the API has been deployed
  • B) To allow breaking changes without disrupting existing clients
  • C) To make URLs longer and more descriptive
  • D) To limit which users can access the API
Show Answer **B) To allow breaking changes without disrupting existing clients** API versioning allows you to introduce breaking changes (renamed fields, removed endpoints, changed response formats) in a new version while continuing to support existing clients on the old version. Common approaches include URL-based versioning (/api/v1/users vs /api/v2/users) and header-based versioning. This is essential for APIs with external consumers who cannot immediately update their code.

Question 21

In a REST API, what should DELETE /api/tasks/42 return if the task does not exist?

  • A) 200 OK with an empty body
  • B) 204 No Content
  • C) 404 Not Found
  • D) Either 404 Not Found or 204 No Content, depending on the API's design philosophy
Show Answer **D) Either 404 Not Found or 204 No Content, depending on the API's design philosophy** This is a legitimate design debate in REST API development. One school of thought says DELETE should return 404 if the resource does not exist, because the client is trying to delete something that is not there. The other school argues that DELETE should be idempotent -- the desired end state (resource gone) is achieved regardless, so 204 is appropriate. Both approaches are valid; the key is to be consistent across your API and document the behavior.

Question 22

What is the N+1 query problem in the context of backend APIs?

  • A) Having too many API endpoints
  • B) Making one query to fetch a list, then N additional queries to fetch related data for each item
  • C) A problem with URL nesting that goes more than one level deep
  • D) An authentication issue where N+1 tokens are required
Show Answer **B) Making one query to fetch a list, then N additional queries to fetch related data for each item** The N+1 query problem occurs when you fetch a list of N items (1 query), then for each item, make an additional query to fetch related data (N queries), resulting in N+1 total queries. For example, fetching 100 tasks and then querying the assignee for each task individually. The fix is to use joins, subqueries, or batch loading to fetch all related data in one or two queries instead.

Question 23

What is the purpose of the lifespan parameter in FastAPI?

  • A) To set how long the server runs before automatically shutting down
  • B) To manage application startup and shutdown events (database connections, background tasks)
  • C) To define the TTL (time to live) for cached responses
  • D) To set JWT token expiration times
Show Answer **B) To manage application startup and shutdown events (database connections, background tasks)** The `lifespan` context manager in FastAPI handles application lifecycle events. Code before `yield` runs during startup (initializing database connections, loading configuration, starting background tasks). Code after `yield` runs during shutdown (closing database connections, flushing logs, stopping background tasks). This replaces the older `on_event("startup")` and `on_event("shutdown")` decorators.

Question 24

Which of these is the best practice for handling sensitive data in API error responses in production?

  • A) Include full stack traces so developers can debug issues
  • B) Return generic error messages without internal details, and log the full details server-side
  • C) Return the raw database error message so the client knows what went wrong
  • D) Disable error handling entirely and let exceptions propagate
Show Answer **B) Return generic error messages without internal details, and log the full details server-side** In production, error responses should be informative enough for the client to understand what went wrong (e.g., "Invalid request" or "Resource not found") without exposing internal implementation details. Stack traces, database error messages, file paths, and internal variable names should never appear in production error responses, as they can be exploited by attackers. Full details should be logged server-side with a request ID that can be used to correlate the client-facing error with the server-side logs.

Question 25

When using AI to generate backend code, which of the following is the most important step?

  • A) Accepting the generated code without review since AI is always correct
  • B) Reviewing the generated code for security vulnerabilities, proper error handling, and correct status codes
  • C) Only using the code if it compiles without warnings
  • D) Rewriting all generated code from scratch to ensure you understand it
Show Answer **B) Reviewing the generated code for security vulnerabilities, proper error handling, and correct status codes** AI-generated backend code often contains subtle issues: hardcoded secrets, missing input validation, incorrect status codes, SQL injection vulnerabilities, or insecure authentication patterns. The most productive approach is to use AI to generate the initial code quickly, then carefully review it for these common problems. You do not need to rewrite everything (that defeats the purpose of AI assistance), but you must review everything, especially security-critical code like authentication, authorization, and data validation.