C
C#7mo ago
ibby

What should the service layer return back to a controller?

Confused about what the service layer should return to the controller, Dtos? Result object? Is this the correct approach?
public async Task<CreateUserResult> CreateUserAsync(string username, string email, string password)
{
...input validation

username = username.ToLower();
email = email.ToLower();

if (_dbContext.Users.Any(x => x.Username.Equals(username)))
{
return; // Return a result object with a bool flag "IsDuplicateUsername"?
}

if (_dbContext.Users.Any(x => x.Email.Equals(email)))
{
return; // Return a result object with a bool flag "IsDuplicateEmail"?
}

var user = new User(username, email, password.ToHash());

await _dbContext.Users.AddAsync(user);

await _dbContext.SaveChangesAsync();

// return result with everything false?
}
public async Task<CreateUserResult> CreateUserAsync(string username, string email, string password)
{
...input validation

username = username.ToLower();
email = email.ToLower();

if (_dbContext.Users.Any(x => x.Username.Equals(username)))
{
return; // Return a result object with a bool flag "IsDuplicateUsername"?
}

if (_dbContext.Users.Any(x => x.Email.Equals(email)))
{
return; // Return a result object with a bool flag "IsDuplicateEmail"?
}

var user = new User(username, email, password.ToHash());

await _dbContext.Users.AddAsync(user);

await _dbContext.SaveChangesAsync();

// return result with everything false?
}
17 Replies
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
mg
mg7mo ago
It does
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
mg
mg7mo ago
@ibby you could either return the created entity and rely on exceptions for error handling, or use a result monad like what OneOf provides Without knowing what your CreateUserResult is it's hard to say if it's right. I'm not sure what you mean by "return result with everything false" As @TeBeClone suggested, you should have username and email be unique on the database, and then you can just call SaveChangesAsync() inside a try/catch to do it all in one database round trip
mg
mg7mo ago
GitHub
GitHub - Giorgi/EntityFramework.Exceptions: Handle database errors ...
Handle database errors easily when working with Entity Framework Core. Supports SQLServer, PostgreSQL, SQLite, Oracle and MySql. - Giorgi/EntityFramework.Exceptions
mg
mg7mo ago
And this will give you an exception that's specific to a unique constraint violation, rather than just a DbUpdateException
ibby
ibbyOP7mo ago
This is what I was thinking at first with return a result. Everything false would mean success
public class CreateUserResult
{
public bool IsUsernameTaken { get; set; } // will map to a BadRequest()
public bool IsEmailAlreadyUsed { get; set; } // will map to a BadRequest()
public bool IsError { get; set; } // will map to a StatusCode(500)
}
public class CreateUserResult
{
public bool IsUsernameTaken { get; set; } // will map to a BadRequest()
public bool IsEmailAlreadyUsed { get; set; } // will map to a BadRequest()
public bool IsError { get; set; } // will map to a StatusCode(500)
}
I think I've seen something like this before, ill check it out. Thanks!
mg
mg7mo ago
I wouldn't do it that way. That requires you to have n different if statements to check each property in your controller
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
mg
mg7mo ago
Whereas with OneOf you can have something like
return result.Match(user => user.MapToResponse(), conflict => conflict.MapToResponse(), error => error.MapToResponse())
return result.Match(user => user.MapToResponse(), conflict => conflict.MapToResponse(), error => error.MapToResponse())
where each different result type has its own mapping method to get mapped to a response And then you can reuse them in other requests too
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
ibby
ibbyOP7mo ago
this is the Result Pattern right?
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
mg
mg7mo ago
Yeah that's what I meant, extension method
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
mg
mg7mo ago
Or I mean it could be a member probably ¯\_(ツ)_/¯
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
Want results from more Discord servers?
Add your server