Skip to content

Instantly share code, notes, and snippets.

@DevJohnC
Created July 18, 2022 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DevJohnC/a85c7da68ed99f6448737b56b8331fb0 to your computer and use it in GitHub Desktop.
Save DevJohnC/a85c7da68ed99f6448737b56b8331fb0 to your computer and use it in GitHub Desktop.
// a webservice
public class MyWebService : Service
{
private IMyService _myService;
public MyWebService(IMyService myService)
{
_myService = myService;
}
public async Task<object> AnyAsync(GetDataRequest request)
{
var result = await _myService.GetDataAsync(request.MyPayloadData);
return result.ToResponse(data => new GetDataResponse
{
ResultData = data
});
}
}
// a service implementation
public class MyServiceImpl : IMyService
{
public async Task<MyDataType> GetDataAsync(MyPayloadDataType payloadData)
{
var matchedRecord = await YourDataSource.TryGetAsync(payloadData);
if (matchedRecord == null)
return ApiError.NotFound;
if (!SecurityService.CanBeReadAsync(matchedRecord))
return ApiError.Forbidden;
return matchedRecord;
}
}
// a OneOf monad for results that can return an instance of T
[GenerateOneOf]
public partial class ServiceResult<T> : OneOfBase<T, ServiceError>
{
}
// a OneOf representing possible errors
[GenerateOneOf]
public partial class ServiceError : OneOfBase<NotFoundServiceResult, ForbiddenServiceResult>
{
public static readonly ServiceError NotFound = new NotFoundServiceResult();
public static readonly ServiceError Forbidden = new ForbiddenServiceResult();
}
// extension methods for mapping ServiceResult<T> to our web services domain
public static class ServiceResultExtensions
{
public static object ToResponse<TResult, TResponse>(
this ServiceResult<TResult> serviceResult,
Func<TResult, TResponse> mapper)
where TResult : notnull
where TResponse : notnull
{
return serviceResult.Match(
x => mapper(x),
error => error.ToResponse());
}
public static object ToResponse(
this ServiceError serviceError)
{
return serviceError.Match(
notfound => new HttpError(HttpStatusCode.NotFound),
forbidden => new HttpError(HttpStatusCode.Forbidden));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment