Implementing delete operations

Now that we have implemented the right filtering logic on the repository side, let's proceed by implementing delete operations in the Catalog.Domain project by adding a new DeleteItemAsync method in the declaration of the IItemService interface:

namespace Catalog.Domain.Services
{
public interface IItemService
{
...
Task<ItemResponse> DeleteItemAsync(DeleteItemRequest request);
}
}

The DeleteItemAsync method refers to a DeleteItemRequest type, which can be declared as follows:

using System;

namespace Catalog.Domain.Requests.Item
{
public class DeleteItemRequest
{
public Guid Id { get; set; }
}
}

Once we update the IItemService interface declaration, we can proceed by adding the implementation to the ItemService concrete class:

public async Task<ItemResponse> DeleteItemAsync(DeleteItemRequest request)
{
if (request?.Id == null) throw new ArgumentNullException();

var result = await _itemRepository.GetAsync(request.Id);
result.IsInactive = true;

_itemRepository.Update(result);
await _itemRepository.UnitOfWork.SaveChangesAsync();

return _itemMapper.Map(result);
}

The DeleteItemAsync method receives an Id field that is part of the DeleteItemRequest class. Besides, it uses the GetAsync method to get the details of the entity, and it continues by calling the Update method by passing the entity with the IsInactive flag set to true. The next step is to implement a new action method in the ItemController that covers the following HTTP call:

DELETE /items/{id}

Moreover, we can proceed by changing the ItemController as follows:

using System;
using System.Threading.Tasks;
using Catalog.API.Filters;
using Catalog.Domain.Requests.Item;
using Microsoft.AspNetCore.Mvc;

namespace Catalog.API.Controllers
{
[Route("api/items")]
[ApiController]
public class ItemController : ControllerBase
{
...

[HttpDelete("{id:guid}")]
[ItemExists]
public async Task<IActionResult> Delete(Guid id)
{
var request = new DeleteItemRequest { Id = id };

await _itemService.DeleteItemAsync(request);

return NoContent();
}
}
}

The Delete action method is decorated with the HttpDelete attribute verb, which means that it is mapped with the HTTP Delete requests. The implementation sets the IsInactive flag through the DeleteItemAsync method, and it returns a NoContent result, which represents an HTTP 204 No Content status code.

We will proceed by testing the changes made to the ItemController class by implementing the following tests:

namespace Catalog.API.Tests.Controllers
{
public class ItemsController : IClassFixture<InMemoryApplicationFactory<Startup>>
{
private readonly InMemoryApplicationFactory<Startup> _factory;

public ItemsController(InMemoryApplicationFactory<Startup> factory)
{
_factory = factory;
}

...

[Theory]
[LoadData("item")]
public async Task delete_should_returns_no_content_when_called_with_right_id(DeleteItemRequest
request)
{
var client = _factory.CreateClient();

var response = await client.DeleteAsync($"/api/items/{request.Id}");

response.StatusCode.ShouldBe(HttpStatusCode.NoContent);
}

[Fact]
public async Task delete_should_returns_not_found_when_called_with_not_existing_id()
{
var client = _factory.CreateClient();

var response = await client.DeleteAsync($"/api/items/{Guid.NewGuid()}");

response.StatusCode.ShouldBe(HttpStatusCode.NotFound);
}
}
}

This test code covers the following two behaviors:

  • The delete_should_returns_no_content_when_called_with_right_id test method checks whether the action method correctly returns the HTTP NoContent response.
  • The delete_should_returns_not_found_when_called_with_not_existing_id method checks that the action method returns HttpStatusCode.NotFound by passing a non-existent GUID (Guid.NewGuid).

In both test cases, we are using the already implemented test infrastructure to verify the new behavior of the web service. In this section, we have seen how to extend our web service in order to support the soft delete operation.

The next section focuses on the implementation of the HATEOAS response approach.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.203.172