5. DTO와 AutoMapper 그리고 Repository

5-2. 비동기 메소드

이 섹션에서는 Entity Framework Core를 사용할 때 비동기 메서드를 활용하는 방법에 대해 배웁니다.

비동기 프로그래밍은 애플리케이션의 성능을 향상시키고, 리소스를 효율적으로 사용할 수 있게 해줍니다.

  • 비동기 메서드로의 전환: 기존의 동기 메서드(.ToList, .FirstOrDefault 등)를 비동기 버전(.ToListAsync, .FirstOrDefaultAsync 등)으로 변경합니다. 이를 위해 await 키워드를 사용하고, 메서드 시그니처에 async 키워드를 추가하여 Task<IActionResult>를 반환하도록 합니다.
  • 비동기 작업의 구현:
    • 조회(Get): .ToListAsync().FirstOrDefaultAsync()를 사용하여 데이터를 비동기적으로 조회합니다.
    • 생성(Post): .AddAsync().SaveChangesAsync()를 사용하여 데이터를 비동기적으로 추가합니다.
    • 업데이트(Put): .SaveChangesAsync()를 사용하여 데이터를 비동기적으로 업데이트합니다.
    • 삭제(Delete): .SaveChangesAsync()를 사용하여 데이터를 비동기적으로 삭제합니다.
    • 패치(Patch): .SaveChangesAsync()를 사용하여 데이터의 일부를 비동기적으로 업데이트합니다.

  • 비동기 메서드의 테스트: 모든 CRUD(Create, Read, Update, Delete) 작업을 비동기 메서드로 전환한 후, 이러한 변경사항이 정상적으로 동작하는지 테스트합니다. 각 작업을 수행하고, 예상대로 데이터가 처리되는지 확인합니다.

  • 비동기 프로그래밍의 장점: 비동기 메서드를 사용함으로써 서버의 리소스를 보다 효율적으로 사용할 수 있으며, 사용자에게 더 빠른 응답 시간을 제공할 수 있습니다. 특히 데이터베이스 작업과 같이 시간이 소요될 수 있는 작업을 처리할 때 유용합니다.


// 조회
public async Task<ActionResult<IEnumerable<PlantDTO>>> GetPlants()
{
    return Ok(await _db.Plants.ToListAsync());
}
​
// 조회 단건
public async Task<ActionResult<PlantDTO>> GetPlant(int id)
{    
    var plant = await _db.Plants.FirstOrDefaultAsync(u => u.Id == id);
    return Ok(plant);
}
​
// 생성 
public async Task<ActionResult<PlantDTO>> CreatePlant([FromBody] PlantCreateDTO plantDTO)
{
    Plant model = new()
    {
        Details = plantDTO.Details,
        ImageUrl = plantDTO.ImageUrl,
        Name = plantDTO.Name,
        Occupancy = plantDTO.Occupancy,
        Rate = plantDTO.Rate,
        Size = plantDTO.Size
    };
    await _db.Plants.AddAsync(model);
    await _db.SaveChangesAsync();
}
​
// 업데이트 
public async Task<IActionResult> UpdatePlant(int id, [FromBody] PlantUpdateDTO plantDTO)
{
    Plant model = new()
    {
        Details = plantDTO.Details,
        Id = plantDTO.Id,
        ImageUrl = plantDTO.ImageUrl,
        Name = plantDTO.Name,
        Occupancy = plantDTO.Occupancy,
        Rate = plantDTO.Rate,
        Size = plantDTO.Size
    };
    _db.Plants.Update(model);
    await _db.SaveChangesAsync();
    return NoContent();
}
​
// 삭제 
public async Task<IActionResult> DeletePlant(int id)
{
    var plant = await _db.Plants.FirstOrDefaultAsync(u => u.Id == id);
    if (plant == null)
    {
        return NotFound();
    }
    _db.Plants.Remove(plant);
    await _db.SaveChangesAsync();
    return NoContent();
}