SSWConsulting / SSW.CleanArchitecture

SSW Clean Architecture Template
https://sswconsulting.github.io/SSW.CleanArchitecture/
MIT License
124 stars 24 forks source link

✨ErrorOr for queries #425

Closed joriente closed 1 week ago

joriente commented 2 weeks ago

Hi

Pain

Wondering if its appropriate to use ErrorOr for queries. I have a query the returns all users for a given institution

public async Task<ErrorOr<PaginatedResult<GetPagedInstitutionUsersDto>>> Handle(
    GetPagedInstitutionUsersQuery request,
    CancellationToken cancellationToken)
{
    var institutionId = new InstitutionId(request.InstitutionId);

    var institution = await dbContext.Institutions
        .WithSpecification(new InstitutionByIdSpec(institutionId))
        .FirstOrDefaultAsync(cancellationToken);

    if (institution is null)
        return InstitutionErrors.NotFound;

    var users = await dbContext.Users
       .WithSpecification(new UsersByInstitutionSpec(request.InstitutionId))
       .ProjectTo<GetPagedInstitutionUsersDto>(mapper.ConfigurationProvider)
       .ToPaginatedListAsync(request.PageNumber, request.PageSize, cancellationToken);

    return users;
}

Then my endpoint looks like this

.MapGet("/pagedinstitutionusers",
    async (ISender sender, [AsParameters] GetPagedInstitutionUsersQuery request, HttpContext context, CancellationToken ct) =>
    {
        var result = await sender.Send(request, ct);
        var results = result.Match(TypedResults.Ok, CustomResult.Problem);
        if (result.IsError)
            return results;

        var metadata = new
        {
            result.Value.TotalPages,
            result.Value.PageSize,
            result.Value.PageNumber,
            result.Value.TotalCount,
            result.Value.HasNextPage,
            result.Value.HasPreviousPage,
        };

        context.Response.Headers["X-Pagination"] = JsonSerializer.Serialize(metadata);
        return TypedResults.Ok(result.Value.Data);
    })
.WithName("GetPagedInstitutionUsers")
.ProducesGet<PaginatedResult<GetPagedInstitutionUsersDto>>();

Which if i supply an institution that does not exists, i get a nice 404 message Image

Not sure if i am doing it the right way though. any guidance is much appreciated

danielmackay commented 1 week ago

Hi @joriente,

Thanks for raising this ticket. Yes, the use of ErrorOr in queries is fine. I noticed we should have used this in the GetTeamQuery so I created a PBI to update this: https://github.com/SSWConsulting/SSW.CleanArchitecture/pull/432/files

You've absolutely done the right thing in your example above. 😄

Cheers, Dan