If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
After all the POST, PUT, idemptotency talk, we deserve a break. There’s only one thing that an API client can’t do to a programmer resource: delete it! So let’s fix that!
Once again, we’re going to leverage HTTP methods. We have GET to retrieve a representation, PUT to update the resource, and DELETE to, ya know, blow the resource up! HTTP gives us these HTTP verbs so that we don’t need to do silly things like have a /api/programmers/delete URI. Remember, every URI is a resource, and that one wouldn’t really make sense you would probably get teased in the cafeteria for it.
Oh where to start? Why not write a test? Open up our feature file and add yet another scenario, this time for deleting a programmer resource. We need to use a Given like in the other scenarios to first make sure that we have a programmer in the database to delete:
# features/api/programmer.feature
# ...
Scenario: DELETE a programmer
Given the following programmers exist:
| nickname | avatarNumber |
| UnitTester | 3 |
When I request "DELETE /api/programmers/UnitTester"
After deleting a resource, what should the endpoint return and what about the status code? People argue about this, but one common approach is to return a 204 status code, which means “No Content”. It’s the server’s way of saying “I completed your request ok, but I really don’t have anything else to tell you beyond that”. In other words, the response will have an empty body:
# features/api/programmer.feature
# ...
Scenario: DELETE a programmer
Given the following programmers exist:
| nickname | avatarNumber |
| UnitTester | 3 |
When I request "DELETE /api/programmers/UnitTester"
Then the response status code should be 204
To make this work, we’ll need to create a route that responds to the HTTP DELETE method. Make sure the URL is the same as what we use to GET one programmer, because we want to take the DELETE action on that resource:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
protected function addRoutes(ControllerCollection $controllers)
{
// ...
$controllers->delete('/api/programmers/{nickname}', array($this, 'deleteAction'));
}
Next, create the deleteAction method. We can copy a little bit of code that queries for a programmer:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function deleteAction($nickname)
{
$programmer = $this->getProgrammerRepository()->findOneByNickname($nickname);
// ...
}
If the programmer exists, let’s eliminate him! I’ve created a shortcut method called delete in my project. Your code will be different, but fortunately, deleting things is pretty easy:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function deleteAction($nickname)
{
// ...
if ($programmer) {
$this->delete($programmer);
}
// ...
}
And finally, we just need to send a Response back to the user. The important part is the 204 status code and the blank content, which is what 204 means:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function deleteAction($nickname)
{
// ...
if ($programmer) {
$this->delete($programmer);
}
return new Response(null, 204);
}
Dang, that was really easy! Execute Behat to make sure we didn’t mess anything up. Awesome! Like with everything else, be consistent with how resources are deleted. Whether you return a 204 status code, or some sort of JSON message, return the same thing for all resources when they’re deleted.
Hey Daan Biesterbos
I think it depends on the App and it's security, some guys would preffer to return the same response whether or not the resource was actually deleted, and some others may preffer to inform the client that the resource was not found.
If the answer to this question "Does a client needs to know when a resource is not found?" is yes, then yes, return a 404. If not, I would hide that information from the client and return a 204.
Cheers!
// composer.json
{
"require": {
"silex/silex": "~1.0", // v1.3.2
"symfony/twig-bridge": "~2.1", // v2.7.3
"symfony/security": "~2.4", // v2.7.3
"doctrine/dbal": "^2.5.4", // v2.5.4
"monolog/monolog": "~1.7.0", // 1.7.0
"symfony/validator": "~2.4", // v2.7.3
"symfony/expression-language": "~2.4" // v2.7.3
},
"require-dev": {
"behat/mink": "~1.5", // v1.5.0
"behat/mink-goutte-driver": "~1.0.9", // v1.0.9
"behat/mink-selenium2-driver": "~1.1.1", // v1.1.1
"behat/behat": "~2.5", // v2.5.5
"behat/mink-extension": "~1.2.0", // v1.2.0
"phpunit/phpunit": "~5.7.0", // 5.7.27
"guzzle/guzzle": "~3.7" // v3.9.3
}
}
Hi there :-)
Usually when I get a DELETE request on a resource that does not exist (or a record that was soft deleted) I return a 404. You did not do this here. What is your opinion on handling that situation?