DELETE'ing Albums [FOSRESTBundle]
At this point we can create new Albums, we can get one, or a collection of existing Albums, and we can update an Album either partially or fully.
Now, we're going to implement the process of deleting individual Albums through our Symfony 4 FOSRESTBundle API.
As with every other HTTP verb, the setup of DELETE
is mostly taken care of for us, so long as we follow the naming convention: deleteAction
.
Before we begin, we have our failing test:
vendor/bin/behat features/album_common.feature --tags=t
Feature: Provide a consistent standard JSON API endpoint
In order to build interchangeable front ends
As a JSON API developer
I need to allow Create, Read, Update, and Delete functionality
Background: # features/album_common.feature:7
Given there are Albums with the following details: # FeatureContext::thereAreAlbumsWithTheFollowingDetails()
| title | track_count | release_date |
| some fake album name | 12 | 2020-01-08T00:00:00+00:00 |
| another great album | 9 | 2019-01-07T23:22:21+00:00 |
| now that's what I call Album vol 2 | 23 | 2018-02-06T11:10:09+00:00 |
And the "Content-Type" request header is "application/json" # Imbo\BehatApiExtension\Context\ApiContext::setRequestHeader()
@t
Scenario: Can delete an Album # features/album_common.feature:43
Given I request "/album/3" using HTTP GET # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 200 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
When I request "/album/3" using HTTP DELETE # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 204 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
Expected response code 204, got 405. (Imbo\BehatApiExtension\Exception\AssertionFailedException)
Then sleep # FeatureContext::sleep()
When I request "/album/3" using HTTP GET # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 404 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
--- Failed scenarios:
features/album_common.feature:43
1 scenario (1 failed)
9 steps (5 passed, 1 failed, 3 skipped)
0m0.13s (9.83Mb)
Right now we're getting a 405
- the method is not implemented.
Implementing DELETE
We start, as usual, by implementing the method stub:
public function deleteAction(string $id)
{
}
And checking the router:
bin/console debug:router
-------------------------- -------- -------- ------ -----------------------------------
Name Method Scheme Host Path
-------------------------- -------- -------- ------ -----------------------------------
cget_album GET ANY ANY /album
get_album GET ANY ANY /album/{id}
post_album POST ANY ANY /album
put_album PUT ANY ANY /album/{id}
patch_album PATCH ANY ANY /album/{id}
delete_album DELETE ANY ANY /album/{id}
-------------------------- -------- -------- ------ -----------------------------------
The process for deleting is quite straightforward.
We start by getting the requested Album
entity by ID.
As we have covered already, if the requested ID is not available, we will throw
, which results in a 404
.
Once we have the Album
entity, we want to call Doctrine's remove
method, followed by immediately flush
ing this change - which deletes the record from the database.
Finally we return a 204
/ No Content response.
Here's the code that does exactly this:
public function deleteAction(string $id)
{
$album = $this->findAlbumById($id);
$this->entityManager->remove($album);
$this->entityManager->flush();
return $this->view(null, Response::HTTP_NO_CONTENT);
}
Really quite straightforward. Honestly this is almost identical to what you'd do with a HTML delete process - maybe throw in a redirect for good measure, but still, very close indeed.
And that gets us to a passing test:
vendor/bin/behat features/album_common.feature --tags=t
Feature: Provide a consistent standard JSON API endpoint
In order to build interchangeable front ends
As a JSON API developer
I need to allow Create, Read, Update, and Delete functionality
Background: # features/album_common.feature:7
Given there are Albums with the following details: # FeatureContext::thereAreAlbumsWithTheFollowingDetails()
| title | track_count | release_date |
| some fake album name | 12 | 2020-01-08T00:00:00+00:00 |
| another great album | 9 | 2019-01-07T23:22:21+00:00 |
| now that's what I call Album vol 2 | 23 | 2018-02-06T11:10:09+00:00 |
And the "Content-Type" request header is "application/json" # Imbo\BehatApiExtension\Context\ApiContext::setRequestHeader()
@t
Scenario: Can delete an Album # features/album_common.feature:43
Given I request "/album/3" using HTTP GET # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 200 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
When I request "/album/3" using HTTP DELETE # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 204 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
Then sleep # FeatureContext::sleep()
When I request "/album/3" using HTTP GET # Imbo\BehatApiExtension\Context\ApiContext::requestPath()
Then the response code is 404 # Imbo\BehatApiExtension\Context\ApiContext::assertResponseCodeIs()
1 scenario (1 passed)
9 steps (9 passed)
0m1.19s (9.80Mb)
That wraps up the happy path.
There's one final step I'd like to take: making the error output match our basic Symfony 4 JSON API. Let's look at that in the next video.