Node.js • Chapter 27 • Beginner Friendly
Express Routing and Middleware
Learn this chapter by understanding what each Node.js feature does, when to use it, how it can fail, and how to verify the result.
27.1 Router Objects
Router Objects is part of Chapter 27, “Express Routing and Middleware.” For a beginner, the first goal is to understand the observable behavior before memorizing an API. In this lesson, middleware means a function placed in a request pipeline to inspect, change, allow, or reject work. The practical focus is middleware order, route matching, request state, and error forwarding.
Start from the smallest working behavior and name every input and output. In Chapter 27 (Express Routing and Middleware), for Router Objects, write down what enters the operation, what Node.js is expected to do, and what the caller can observe afterward. If the result is asynchronous, also state when completion is known and where errors travel.
For Router Objects in Chapter 27, the mechanism to keep in mind is separating routing, validation, authentication, and response logic. A good experiment changes one thing at a time and checks both success and failure. When you finish this topic, you should be able to explain why the code works, not only copy the syntax.
Key terms in plain language
- middleware — a function placed in a request pipeline to inspect, change, allow, or reject work.
- Router — a concrete part of router objects that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
- Objects — a concrete part of router objects that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
10 teaching examples
Example 1: Failure you can recognize
For Express Routing and Middleware, create a safe failure involving Router Objects, such as invalid data, a missing resource, a closed connection, or a rejected promise. Observe the error type and decide where the program should handle it rather than hiding it.
Example 2: Real service scenario
Imagine a small tutoring-service backend applying Router Objects during Chapter 27 (Express Routing and Middleware). State what arrives from the caller, what the Node.js process must do, what it returns, and what must be logged if the operation fails.
Example 3: Security or trust check
In the Express Routing and Middleware context, treat one value used by Router Objects as untrusted. Identify what must be validated, encoded, bounded, or refused before the value reaches a sensitive operation. Explain the consequence of trusting it blindly.
Example 4: Concurrency check
For Chapter 27, run or reason about two Router Objects operations close together. Ask whether ordering matters, whether shared state can conflict, and whether work should be awaited, queued, streamed, or moved to another worker.
Example 5: Performance check
While studying Express Routing and Middleware, measure the resource most affected by Router Objects: elapsed time, bytes, memory, open connections, event-loop delay, or database round trips. Optimize only after the measurement identifies a meaningful cost.
Example 6: Refactoring example
In a Express Routing and Middleware exercise, take code that mixes Router Objects with unrelated business logic and split it into a small function with an explicit input and return value. The caller should not need to know low-level details unless they are part of the contract.
Example 7: Production reasoning
Assume the Router Objects code from Chapter 27 runs thousands of times. Decide what needs a timeout, limit, retry rule, cleanup step, metric, or graceful-shutdown hook. The goal is predictable behavior under repetition, load, and partial failure.
Example 8: Minimal working case
In Chapter 27 (Express Routing and Middleware), build the smallest Router Objects example that has one clear input and one visible result. Before running it, write what you expect to happen. Then verify middleware order, route matching, request state, and error forwarding. This establishes a baseline you can reason about.
Example 9: Change one input
For Chapter 27 (Express Routing and Middleware), keep the same program but change exactly one input related to Router Objects. Compare the two outputs and explain why the change happened. This teaches cause and effect instead of memorizing syntax.
Example 10: Compare two approaches
Within Express Routing and Middleware, solve one tiny task twice: first with the most direct approach to Router Objects, then with a reasonable alternative. Compare readability, error behavior, and resource use. Choose the version whose tradeoff matches the task.
Node.js coding example
// Topic: Router Objects
// Install first: npm install express
import express from 'express';
const app = express();
app.use(express.json({ limit: '32kb' }));
app.get('/lesson', (req, res) => {
res.json({ chapter: 27, topic: "Router Objects" });
});
const server = app.listen(0, () => {
console.log('ready', server.address().port);
server.close();
});Step-by-step code explanation
- Create an Express application.
- Add bounded JSON-body parsing before routes that need it.
- Return JSON from a GET route.
- Listen briefly on a free port and then close the example server.
Expected output: ready followed by a free local port number.
Practice exercise
Build a small Chapter 27 example for Router Objects. Write the expected result before running it. Add one failure case, then change exactly one condition and explain why the behavior changed. For production reasoning, identify one limit, timeout, cleanup step, or validation rule that would make the code safer.
27.2 Route Parameters and Query Values
Route Parameters and Query Values is part of Chapter 27, “Express Routing and Middleware.” For a beginner, the first goal is to understand the observable behavior before memorizing an API. In this lesson, middleware means a function placed in a request pipeline to inspect, change, allow, or reject work. The practical focus is middleware order, route matching, request state, and error forwarding.
Compare the correct approach with a common alternative so the tradeoff is visible. In Chapter 27 (Express Routing and Middleware), the useful comparison for Route Parameters and Query Values is not “short code versus long code”; it is predictable behavior versus hidden assumptions. Check platform differences, lifetime of resources, and whether the caller must wait for completion.
For Route Parameters and Query Values in Chapter 27, the mechanism to keep in mind is separating routing, validation, authentication, and response logic. A good experiment changes one thing at a time and checks both success and failure. When you finish this topic, you should be able to explain why the code works, not only copy the syntax.
Key terms in plain language
- middleware — a function placed in a request pipeline to inspect, change, allow, or reject work.
- Route — a concrete part of route parameters and query values that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
- Parameters — a concrete part of route parameters and query values that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
- Query — a concrete part of route parameters and query values that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
10 teaching examples
Example 1: Security or trust check
In the Express Routing and Middleware context, treat one value used by Route Parameters and Query Values as untrusted. Identify what must be validated, encoded, bounded, or refused before the value reaches a sensitive operation. Explain the consequence of trusting it blindly.
Example 2: Concurrency check
For Chapter 27, run or reason about two Route Parameters and Query Values operations close together. Ask whether ordering matters, whether shared state can conflict, and whether work should be awaited, queued, streamed, or moved to another worker.
Example 3: Performance check
While studying Express Routing and Middleware, measure the resource most affected by Route Parameters and Query Values: elapsed time, bytes, memory, open connections, event-loop delay, or database round trips. Optimize only after the measurement identifies a meaningful cost.
Example 4: Refactoring example
In a Express Routing and Middleware exercise, take code that mixes Route Parameters and Query Values with unrelated business logic and split it into a small function with an explicit input and return value. The caller should not need to know low-level details unless they are part of the contract.
Example 5: Production reasoning
Assume the Route Parameters and Query Values code from Chapter 27 runs thousands of times. Decide what needs a timeout, limit, retry rule, cleanup step, metric, or graceful-shutdown hook. The goal is predictable behavior under repetition, load, and partial failure.
Example 6: Minimal working case
In Chapter 27 (Express Routing and Middleware), build the smallest Route Parameters and Query Values example that has one clear input and one visible result. Before running it, write what you expect to happen. Then verify middleware order, route matching, request state, and error forwarding. This establishes a baseline you can reason about.
Example 7: Change one input
For Chapter 27 (Express Routing and Middleware), keep the same program but change exactly one input related to Route Parameters and Query Values. Compare the two outputs and explain why the change happened. This teaches cause and effect instead of memorizing syntax.
Example 8: Compare two approaches
Within Express Routing and Middleware, solve one tiny task twice: first with the most direct approach to Route Parameters and Query Values, then with a reasonable alternative. Compare readability, error behavior, and resource use. Choose the version whose tradeoff matches the task.
Example 9: Failure you can recognize
For Express Routing and Middleware, create a safe failure involving Route Parameters and Query Values, such as invalid data, a missing resource, a closed connection, or a rejected promise. Observe the error type and decide where the program should handle it rather than hiding it.
Example 10: Real service scenario
Imagine a small tutoring-service backend applying Route Parameters and Query Values during Chapter 27 (Express Routing and Middleware). State what arrives from the caller, what the Node.js process must do, what it returns, and what must be logged if the operation fails.
Node.js coding example
// Topic: Route Parameters and Query Values
// Install first: npm install express
import express from 'express';
const app = express();
app.use(express.json({ limit: '32kb' }));
app.get('/lesson', (req, res) => {
res.json({ chapter: 27, topic: "Route Parameters and Query Values" });
});
const server = app.listen(0, () => {
console.log('ready', server.address().port);
server.close();
});Step-by-step code explanation
- Create an Express application.
- Add bounded JSON-body parsing before routes that need it.
- Return JSON from a GET route.
- Listen briefly on a free port and then close the example server.
Expected output: ready followed by a free local port number.
Practice exercise
Build a small Chapter 27 example for Route Parameters and Query Values. Write the expected result before running it. Add one failure case, then change exactly one condition and explain why the behavior changed. For production reasoning, identify one limit, timeout, cleanup step, or validation rule that would make the code safer.
27.3 Middleware Order
Middleware Order is part of Chapter 27, “Express Routing and Middleware.” For a beginner, the first goal is to understand the observable behavior before memorizing an API. In this lesson, middleware means a function placed in a request pipeline to inspect, change, allow, or reject work. The practical focus is middleware order, route matching, request state, and error forwarding.
Deliberately inspect a failure case because error behavior is part of the API. In Chapter 27 (Express Routing and Middleware), a robust understanding of Middleware Order includes its failure path. Ask what happens with missing data, invalid input, a closed resource, cancellation, or partial completion. Handling those cases deliberately is part of correct Node.js design.
For Middleware Order in Chapter 27, the mechanism to keep in mind is separating routing, validation, authentication, and response logic. A good experiment changes one thing at a time and checks both success and failure. When you finish this topic, you should be able to explain why the code works, not only copy the syntax.
Key terms in plain language
- middleware — a function placed in a request pipeline to inspect, change, allow, or reject work.
- Order — a concrete part of middleware order that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
10 teaching examples
Example 1: Performance check
While studying Express Routing and Middleware, measure the resource most affected by Middleware Order: elapsed time, bytes, memory, open connections, event-loop delay, or database round trips. Optimize only after the measurement identifies a meaningful cost.
Example 2: Refactoring example
In a Express Routing and Middleware exercise, take code that mixes Middleware Order with unrelated business logic and split it into a small function with an explicit input and return value. The caller should not need to know low-level details unless they are part of the contract.
Example 3: Production reasoning
Assume the Middleware Order code from Chapter 27 runs thousands of times. Decide what needs a timeout, limit, retry rule, cleanup step, metric, or graceful-shutdown hook. The goal is predictable behavior under repetition, load, and partial failure.
Example 4: Minimal working case
In Chapter 27 (Express Routing and Middleware), build the smallest Middleware Order example that has one clear input and one visible result. Before running it, write what you expect to happen. Then verify middleware order, route matching, request state, and error forwarding. This establishes a baseline you can reason about.
Example 5: Change one input
For Chapter 27 (Express Routing and Middleware), keep the same program but change exactly one input related to Middleware Order. Compare the two outputs and explain why the change happened. This teaches cause and effect instead of memorizing syntax.
Example 6: Compare two approaches
Within Express Routing and Middleware, solve one tiny task twice: first with the most direct approach to Middleware Order, then with a reasonable alternative. Compare readability, error behavior, and resource use. Choose the version whose tradeoff matches the task.
Example 7: Failure you can recognize
For Express Routing and Middleware, create a safe failure involving Middleware Order, such as invalid data, a missing resource, a closed connection, or a rejected promise. Observe the error type and decide where the program should handle it rather than hiding it.
Example 8: Real service scenario
Imagine a small tutoring-service backend applying Middleware Order during Chapter 27 (Express Routing and Middleware). State what arrives from the caller, what the Node.js process must do, what it returns, and what must be logged if the operation fails.
Example 9: Security or trust check
In the Express Routing and Middleware context, treat one value used by Middleware Order as untrusted. Identify what must be validated, encoded, bounded, or refused before the value reaches a sensitive operation. Explain the consequence of trusting it blindly.
Example 10: Concurrency check
For Chapter 27, run or reason about two Middleware Order operations close together. Ask whether ordering matters, whether shared state can conflict, and whether work should be awaited, queued, streamed, or moved to another worker.
Node.js coding example
// Topic: Middleware Order
// Install first: npm install express
import express from 'express';
const app = express();
app.use(express.json({ limit: '32kb' }));
app.get('/lesson', (req, res) => {
res.json({ chapter: 27, topic: "Middleware Order" });
});
const server = app.listen(0, () => {
console.log('ready', server.address().port);
server.close();
});Step-by-step code explanation
- Create an Express application.
- Add bounded JSON-body parsing before routes that need it.
- Return JSON from a GET route.
- Listen briefly on a free port and then close the example server.
Expected output: ready followed by a free local port number.
Practice exercise
Build a small Chapter 27 example for Middleware Order. Write the expected result before running it. Add one failure case, then change exactly one condition and explain why the behavior changed. For production reasoning, identify one limit, timeout, cleanup step, or validation rule that would make the code safer.
27.4 Error-Handling Middleware
Error-Handling Middleware is part of Chapter 27, “Express Routing and Middleware.” For a beginner, the first goal is to understand the observable behavior before memorizing an API. In this lesson, middleware means a function placed in a request pipeline to inspect, change, allow, or reject work. The practical focus is middleware order, route matching, request state, and error forwarding.
Connect the idea to a small service or automation task that a learner could actually build. In Chapter 27 (Express Routing and Middleware), connect Error-Handling Middleware to a small backend, automation script, or command-line tool. That makes the API easier to remember because each method call has a reason, a boundary, and an expected result.
For Error-Handling Middleware in Chapter 27, the mechanism to keep in mind is separating routing, validation, authentication, and response logic. A good experiment changes one thing at a time and checks both success and failure. When you finish this topic, you should be able to explain why the code works, not only copy the syntax.
Key terms in plain language
- middleware — a function placed in a request pipeline to inspect, change, allow, or reject work.
- Error-Handling — a concrete part of error-handling middleware that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
10 teaching examples
Example 1: Production reasoning
Assume the Error-Handling Middleware code from Chapter 27 runs thousands of times. Decide what needs a timeout, limit, retry rule, cleanup step, metric, or graceful-shutdown hook. The goal is predictable behavior under repetition, load, and partial failure.
Example 2: Minimal working case
In Chapter 27 (Express Routing and Middleware), build the smallest Error-Handling Middleware example that has one clear input and one visible result. Before running it, write what you expect to happen. Then verify middleware order, route matching, request state, and error forwarding. This establishes a baseline you can reason about.
Example 3: Change one input
For Chapter 27 (Express Routing and Middleware), keep the same program but change exactly one input related to Error-Handling Middleware. Compare the two outputs and explain why the change happened. This teaches cause and effect instead of memorizing syntax.
Example 4: Compare two approaches
Within Express Routing and Middleware, solve one tiny task twice: first with the most direct approach to Error-Handling Middleware, then with a reasonable alternative. Compare readability, error behavior, and resource use. Choose the version whose tradeoff matches the task.
Example 5: Failure you can recognize
For Express Routing and Middleware, create a safe failure involving Error-Handling Middleware, such as invalid data, a missing resource, a closed connection, or a rejected promise. Observe the error type and decide where the program should handle it rather than hiding it.
Example 6: Real service scenario
Imagine a small tutoring-service backend applying Error-Handling Middleware during Chapter 27 (Express Routing and Middleware). State what arrives from the caller, what the Node.js process must do, what it returns, and what must be logged if the operation fails.
Example 7: Security or trust check
In the Express Routing and Middleware context, treat one value used by Error-Handling Middleware as untrusted. Identify what must be validated, encoded, bounded, or refused before the value reaches a sensitive operation. Explain the consequence of trusting it blindly.
Example 8: Concurrency check
For Chapter 27, run or reason about two Error-Handling Middleware operations close together. Ask whether ordering matters, whether shared state can conflict, and whether work should be awaited, queued, streamed, or moved to another worker.
Example 9: Performance check
While studying Express Routing and Middleware, measure the resource most affected by Error-Handling Middleware: elapsed time, bytes, memory, open connections, event-loop delay, or database round trips. Optimize only after the measurement identifies a meaningful cost.
Example 10: Refactoring example
In a Express Routing and Middleware exercise, take code that mixes Error-Handling Middleware with unrelated business logic and split it into a small function with an explicit input and return value. The caller should not need to know low-level details unless they are part of the contract.
Node.js coding example
// Topic: Error-Handling Middleware
// Install first: npm install express
import express from 'express';
const app = express();
app.use(express.json({ limit: '32kb' }));
app.get('/lesson', (req, res) => {
res.json({ chapter: 27, topic: "Error-Handling Middleware" });
});
const server = app.listen(0, () => {
console.log('ready', server.address().port);
server.close();
});Step-by-step code explanation
- Create an Express application.
- Add bounded JSON-body parsing before routes that need it.
- Return JSON from a GET route.
- Listen briefly on a free port and then close the example server.
Expected output: ready followed by a free local port number.
Practice exercise
Build a small Chapter 27 example for Error-Handling Middleware. Write the expected result before running it. Add one failure case, then change exactly one condition and explain why the behavior changed. For production reasoning, identify one limit, timeout, cleanup step, or validation rule that would make the code safer.
27.5 Async Route Handlers
Async Route Handlers is part of Chapter 27, “Express Routing and Middleware.” For a beginner, the first goal is to understand the observable behavior before memorizing an API. In this lesson, middleware means a function placed in a request pipeline to inspect, change, allow, or reject work. The practical focus is completion order, rejection paths, and concurrency limits.
Finish by asking what changes when the code runs repeatedly, concurrently, or with untrusted input. In Chapter 27 (Express Routing and Middleware), production code using Async Route Handlers should be reviewable by another developer. Keep responsibilities small, add limits around untrusted or repeated work, and record enough context to diagnose failures without exposing secrets.
For Async Route Handlers in Chapter 27, the mechanism to keep in mind is separating routing, validation, authentication, and response logic. A good experiment changes one thing at a time and checks both success and failure. When you finish this topic, you should be able to explain why the code works, not only copy the syntax.
Key terms in plain language
- middleware — a function placed in a request pipeline to inspect, change, allow, or reject work.
- Async — a concrete part of async route handlers that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
- Route — a concrete part of async route handlers that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
- Handlers — a concrete part of async route handlers that the lesson isolates so you can see its effect instead of treating the whole feature as a black box.
10 teaching examples
Example 1: Change one input
For Chapter 27 (Express Routing and Middleware), keep the same program but change exactly one input related to Async Route Handlers. Compare the two outputs and explain why the change happened. This teaches cause and effect instead of memorizing syntax.
Example 2: Compare two approaches
Within Express Routing and Middleware, solve one tiny task twice: first with the most direct approach to Async Route Handlers, then with a reasonable alternative. Compare readability, error behavior, and resource use. Choose the version whose tradeoff matches the task.
Example 3: Failure you can recognize
For Express Routing and Middleware, create a safe failure involving Async Route Handlers, such as invalid data, a missing resource, a closed connection, or a rejected promise. Observe the error type and decide where the program should handle it rather than hiding it.
Example 4: Real service scenario
Imagine a small tutoring-service backend applying Async Route Handlers during Chapter 27 (Express Routing and Middleware). State what arrives from the caller, what the Node.js process must do, what it returns, and what must be logged if the operation fails.
Example 5: Security or trust check
In the Express Routing and Middleware context, treat one value used by Async Route Handlers as untrusted. Identify what must be validated, encoded, bounded, or refused before the value reaches a sensitive operation. Explain the consequence of trusting it blindly.
Example 6: Concurrency check
For Chapter 27, run or reason about two Async Route Handlers operations close together. Ask whether ordering matters, whether shared state can conflict, and whether work should be awaited, queued, streamed, or moved to another worker.
Example 7: Performance check
While studying Express Routing and Middleware, measure the resource most affected by Async Route Handlers: elapsed time, bytes, memory, open connections, event-loop delay, or database round trips. Optimize only after the measurement identifies a meaningful cost.
Example 8: Refactoring example
In a Express Routing and Middleware exercise, take code that mixes Async Route Handlers with unrelated business logic and split it into a small function with an explicit input and return value. The caller should not need to know low-level details unless they are part of the contract.
Example 9: Production reasoning
Assume the Async Route Handlers code from Chapter 27 runs thousands of times. Decide what needs a timeout, limit, retry rule, cleanup step, metric, or graceful-shutdown hook. The goal is predictable behavior under repetition, load, and partial failure.
Example 10: Minimal working case
In Chapter 27 (Express Routing and Middleware), build the smallest Async Route Handlers example that has one clear input and one visible result. Before running it, write what you expect to happen. Then verify completion order, rejection paths, and concurrency limits. This establishes a baseline you can reason about.
Node.js coding example
// Topic: Async Route Handlers
// Install first: npm install express
import express from 'express';
const app = express();
app.use(express.json({ limit: '32kb' }));
app.get('/lesson', (req, res) => {
res.json({ chapter: 27, topic: "Async Route Handlers" });
});
const server = app.listen(0, () => {
console.log('ready', server.address().port);
server.close();
});Step-by-step code explanation
- Create an Express application.
- Add bounded JSON-body parsing before routes that need it.
- Return JSON from a GET route.
- Listen briefly on a free port and then close the example server.
Expected output: ready followed by a free local port number.
Practice exercise
Build a small Chapter 27 example for Async Route Handlers. Write the expected result before running it. Add one failure case, then change exactly one condition and explain why the behavior changed. For production reasoning, identify one limit, timeout, cleanup step, or validation rule that would make the code safer.
Chapter 27 review — 20 questions and answers
1. What is the main purpose of Router Objects?
Answer: Its purpose is to make Router Objects explicit and observable so the program can use it predictably rather than relying on hidden assumptions.
2. What should a beginner identify before using Router Objects?
Answer: Identify the input, expected output, completion signal, possible error, and any resource that must be released.
3. Why is error handling important for Router Objects?
Answer: Because real inputs and resources fail. Correct code defines how the failure is reported and what cleanup still must happen.
4. How can you test Router Objects safely?
Answer: Start with a tiny deterministic case, test one failure case, then add concurrency or untrusted input only after the baseline is understood.
5. What is the main purpose of Route Parameters and Query Values?
Answer: Its purpose is to make Route Parameters and Query Values explicit and observable so the program can use it predictably rather than relying on hidden assumptions.
6. What should a beginner identify before using Route Parameters and Query Values?
Answer: Identify the input, expected output, completion signal, possible error, and any resource that must be released.
7. Why is error handling important for Route Parameters and Query Values?
Answer: Because real inputs and resources fail. Correct code defines how the failure is reported and what cleanup still must happen.
8. How can you test Route Parameters and Query Values safely?
Answer: Start with a tiny deterministic case, test one failure case, then add concurrency or untrusted input only after the baseline is understood.
9. What is the main purpose of Middleware Order?
Answer: Its purpose is to make Middleware Order explicit and observable so the program can use it predictably rather than relying on hidden assumptions.
10. What should a beginner identify before using Middleware Order?
Answer: Identify the input, expected output, completion signal, possible error, and any resource that must be released.
11. Why is error handling important for Middleware Order?
Answer: Because real inputs and resources fail. Correct code defines how the failure is reported and what cleanup still must happen.
12. How can you test Middleware Order safely?
Answer: Start with a tiny deterministic case, test one failure case, then add concurrency or untrusted input only after the baseline is understood.
13. What is the main purpose of Error-Handling Middleware?
Answer: Its purpose is to make Error-Handling Middleware explicit and observable so the program can use it predictably rather than relying on hidden assumptions.
14. What should a beginner identify before using Error-Handling Middleware?
Answer: Identify the input, expected output, completion signal, possible error, and any resource that must be released.
15. Why is error handling important for Error-Handling Middleware?
Answer: Because real inputs and resources fail. Correct code defines how the failure is reported and what cleanup still must happen.
16. How can you test Error-Handling Middleware safely?
Answer: Start with a tiny deterministic case, test one failure case, then add concurrency or untrusted input only after the baseline is understood.
17. What is the main purpose of Async Route Handlers?
Answer: Its purpose is to make Async Route Handlers explicit and observable so the program can use it predictably rather than relying on hidden assumptions.
18. What should a beginner identify before using Async Route Handlers?
Answer: Identify the input, expected output, completion signal, possible error, and any resource that must be released.
19. Why is error handling important for Async Route Handlers?
Answer: Because real inputs and resources fail. Correct code defines how the failure is reported and what cleanup still must happen.
20. How can you test Async Route Handlers safely?
Answer: Start with a tiny deterministic case, test one failure case, then add concurrency or untrusted input only after the baseline is understood.