0

I want to build asynchronous Web API using .NET Core

If I have async Task that's awaiting for a result from the service as below

        [HttpGet("User/")]
        public async Task<IActionResult> GetUser()
        {
            var result = await _service.GetUser();
            return Ok(result);
        }

Now in _service.GetUser we do more than one task such as querying the database more than once.

So my question is do we have to use async & await as well in _service.GetUser, or is it enough that the caller method do? I'm kind of confused.

    public async Task<UserResponseDTO> GetUser(UserRequestDTO userRequestDTO)
    {
        var userId =  await _utilities.getUserId(); //shall we use it?
        var user = await _dbContext.getFullUserInfo //shall we use it?
           .Where(P => P.userId == userId).FirstOrDefault();
   

        if (!string.IsNullOrEmpty(userRequestDTO.email))
        {
            var emailExists = await _dbContext.getFullUserInfo.Where(p => 
             p.Email == userRequestDTO.email).AnyAsync();  //shall we use it?
        }
    
        await _dbContext.SaveChangesAsync();
        return _mapper.Map<UserResponseDTO>(user);
    }
10
  • 2
    You should do async/await all the way from the top to the bottom of the methods you are calling, so it is correct to make GetUser async and await the async calls in it. Although I don't think you need the SaveChangesAsync as it does not appear that you actually change anything. Commented Aug 2, 2021 at 16:23
  • 1
    How would you implement that method without using await? Obviously it's possible (asynchronous programming was done before await was even added to the language) but await was specifically added because it's much easier than the alternative. If you just removed the await keyword and did nothing else then of course the whole thing wouldn't even compile, so you need to do something. Commented Aug 2, 2021 at 16:25
  • Imagine this was the case and the need to use await inside a routine depended on the caller of the routine. How can you know if your caller is using it? And even if you did somehow know that, both awaiting a task immediately and storing it to be awaited later are valid techniques, how would you distinguish between them? Commented Aug 2, 2021 at 16:25
  • @juharr Thanks for the reply . Actually SaveChangesAsync() is needed but I had to remove some of the code for simplicity Commented Aug 2, 2021 at 17:07
  • @Servy I was doing await in GetUser for one call to db. Then as my calls to db increase I felt there's somthing odd to repeat await for each Commented Aug 2, 2021 at 17:09

1 Answer 1

2

I want to build asynchronous Web API Using .NET Core

Why?

There are a number of incorrect answers to that question; the most common one is probably "to make it faster". "To make it more scalable" I would say is only semi-correct.

The correct answer is "I have asynchronous work do to", where "asynchronous" in this context is roughly the same as "I/O-bound".

In your example code, you want an asynchronous Web API call because that call queries/updates the database.

So my question is do we have to use async & await as well in _service.GetUser or is it enough that the caller method do?

Once you have the correct reasoning around "why", the solution is clearer. Specifically, you want to have asynchronous database methods first, and then make your API method asynchronous if it calls them.

Generally, it's best to start at the lowest-level calls and make those use await. FirstOrDefaultAsync, AnyAsync, SaveChangesAsync, etc. Anything doing I/O can be changed to use await. Once GetUser is an asynchronous method (and should be called GetUserAsync), then make your GetUser action method use async/await.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.