Item Validation in APIs
Introduction: Why Validate Item-Level Requests?
Welcome back! In the previous lesson, you learned how to organize your backend code using a service layer. Now, let’s focus on a key part of building reliable APIs: validation — especially when working with item-level endpoints, such as updating or deleting a single task.
When a user sends data to your API (for example, to update a task), you want to make sure that data is correct and safe before you use it. If you skip validation, your app could break or store bad data. In this lesson, you’ll see how to check incoming data for common problems and return helpful error messages if something is wrong.
This is especially important when working with endpoints like PUT and PATCH, which update existing data. These two methods behave differently:
PUTexpects all fields to be sent and replaces the entire object.PATCHexpects only the fields that should be updated. We’ll validate differently depending on which one the client uses — and that’s where thepartialflag comes into play.
From Service Logic to Validation
Before jumping into validation, let’s take a moment to connect what we’ve already built:
- We have a
Tasktype that defines the structure of our tasks:id,title,content,completed, and optionaldueDate. - We created a service layer (
taskService.ts) to isolate task-related operations likegetTaskByIdandupdateTaskById. This helps us keep our API routes clean. - Now, we’re focusing on making sure the data sent to those service functions is valid, especially for update operations (
PUTandPATCH).
The updateTaskById function accepts a partial flag that determines whether a full (PUT) or partial (PATCH) update is expected. The validation function we’ll build will use this flag to check the data accordingly.
We’ll focus on the updateTaskById function and how to validate the data it receives.
How The `validateTaskPayload` Function Works
To make sure only valid data is accepted, we use a function called validateTaskPayload. This function checks the incoming data and returns a list of errors if something is wrong.
Here’s the function:
Let’s break down what this function does:
-
Checks if the payload is an object:
If the data sent is not a JSON object, it returns an error. -
Checks for unexpected fields:
Onlytitle,content,completed, anddueDateare allowed. If there’s anything else, it adds an error. -
Checks for required fields:
Ifpartialisfalse, all fields exceptdueDateare required. -
Checks data types:
titleandcontentmust be strings.completedmust be a boolean (trueorfalse).dueDatemust be a string in date format (if provided).
Example:
This helps us catch mistakes before they cause problems in our app. Notice how multiple validation errors are returned at once. This design improves the developer experience — the client can fix all the issues in one go rather than having to retry multiple times for each error.
