Updating and Deleting Records
The update and delete endpoints follow a similar pattern to get_one(): they accept an ID from the URL, verify the record exists, perform the operation, and return an appropriate response.
Updating a Record - PUT
The update() endpoint combines patterns from get_one() (ID extraction, existence check) and create() (JSON parsing, validation):
public function update(): void {
$this->authenticate();
$update_id = segment(3, 'int');
if ($update_id === 0) {
http_response_code(400);
echo json_encode([
'error' => 'No country ID provided.'
]);
return;
}
$existing = $this->model->get_one($update_id);
if ($existing === false) {
http_response_code(404);
echo json_encode([
'error' => 'Country not found.'
]);
return;
}
$data = $this->get_post_data();
if ($data === null) {
http_response_code(400);
echo json_encode([
'error' => 'Invalid or missing JSON payload.'
]);
return;
}
$validation_errors = $this->validate($data);
if (!empty($validation_errors)) {
http_response_code(400);
echo json_encode([
'error' => 'Validation failed.',
'fields' => $validation_errors
]);
return;
}
$this->model->update($update_id, $data);
http_response_code(200);
echo json_encode([
'message' => 'Country updated successfully.',
'id' => $update_id,
'country' => $data
]);
$this->log_request('update', $update_id);
}The method checks each precondition in order and returns early if any check fails. This is sometimes called the guard clause pattern - validate everything before doing work, and return immediately on the first error.
The Model Update
public function update(int $update_id, array $data): void {
$update_data = [
'country_title' => trim($data['country_title']),
'country_code' => strtoupper(
trim($data['country_code'])
)
];
$this->db->update(
$update_id, $update_data, 'countries'
);
}Deleting a Record - DELETE
The destroy() endpoint is the simplest of the write operations:
public function destroy(): void {
$this->authenticate();
$update_id = segment(3, 'int');
if ($update_id === 0) {
http_response_code(400);
echo json_encode([
'error' => 'No country ID provided.'
]);
return;
}
$existing = $this->model->get_one($update_id);
if ($existing === false) {
http_response_code(404);
echo json_encode([
'error' => 'Country not found.'
]);
return;
}
$this->model->destroy($update_id);
http_response_code(200);
echo json_encode([
'message' => 'Country deleted successfully.'
]);
$this->log_request('destroy', $update_id);
}200 vs 204 for Deletion
You may have seen REST APIs that return 204 No Content after a successful deletion. There is genuine debate about which is correct. We use 200 in this chapter because we include a confirmation message in the response body, which provides a better developer experience - the client can display "Country deleted successfully" to the user without needing to synthesise their own success message.
If you prefer the purist approach, simply change http_response_code(200) to http_response_code(204) and omit the echo json_encode(...) line. Both are valid.
Testing
# Update a record
curl -X PUT \
-H "Trongatetoken: your-token" \
-H "Content-Type: application/json" \
-d '{"country_title":"New Name","country_code":"NN"}' \
http://localhost/countries_api/update/1
# Delete a record
curl -X DELETE \
-H "Trongatetoken: your-token" \
http://localhost/countries_api/destroy/1
# Update non-existent record
curl -X PUT \
-H "Trongatetoken: your-token" \
-H "Content-Type: application/json" \
-d '{"country_title":"Nope","country_code":"NP"}' \
http://localhost/countries_api/update/999
The third test case - attempting to update a record that does not exist - should return 404 Not Found with an informative error message.
We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.
Share your thoughts in the Documentation Feedback.