Skip to content

Commit 98e2de9

Browse files
authored
Merge pull request #32 from umbraco/feature/use-attempt
Refactors the IAuthorizedServiceCaller methods to use Attempt
2 parents f6307cb + effcaf3 commit 98e2de9

17 files changed

+434
-296
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ To make a call to an authorized service, you first need to obtain an instance of
208208
If making a request where all information is provided via the path and querystring, such as GET requests, the following method should be invoked:
209209

210210
```csharp
211-
Task<TResponse> SendRequestAsync<TResponse>(string serviceAlias, string path, HttpMethod httpMethod);
211+
Task<Attempt<TResponse?>> SendRequestAsync<TResponse>(string serviceAlias, string path, HttpMethod httpMethod);
212212
```
213213

214214
The parameters for the request are as follows:
@@ -223,7 +223,7 @@ There is also a type parameter:
223223
If you need to provide data in the request, as is usually the case for POST or PUT requests that required the creation or update of a resource, an overload is available:
224224

225225
```csharp
226-
Task<TResponse> SendRequestAsync<TRequest, TResponse>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
226+
Task<Attempt<TResponse>> SendRequestAsync<TRequest, TResponse>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
227227
where TRequest : class;
228228
```
229229

@@ -238,16 +238,16 @@ And additional type parameter:
238238
If you need to work with the raw JSON response, there are equivalent methods for both of these that omit the deserialization step:
239239

240240
```csharp
241-
Task<string> SendRequestRawAsync(string serviceAlias, string path, HttpMethod httpMethod);
241+
Task<Attempt<string?>> SendRequestRawAsync(string serviceAlias, string path, HttpMethod httpMethod);
242242

243-
Task<string> SendRequestRawAsync<TRequest>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
243+
Task<<Attempt<string?>> SendRequestRawAsync<TRequest>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
244244
where TRequest : class;
245245
```
246246

247247
Finally, there are convenience extension methods available for each of the common HTTP verbs, allowing you to simplify the requests and omit the `HttpMethod` parameter, e.g.
248248

249249
```csharp
250-
Task<TResponse> GetRequestAsync<TResponse>(string serviceAlias, string path);
250+
Task<Attempt<TResponse?>> GetRequestAsync<TResponse>(string serviceAlias, string path);
251251
```
252252

253253
## Providers
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.Net;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Umbraco.AuthorizedServices.Exceptions;
4+
using Umbraco.AuthorizedServices.Services;
5+
using Umbraco.Cms.Web.Common.Controllers;
6+
7+
namespace Umbraco.AuthorizedServices.TestSite.Controllers;
8+
9+
public abstract class AuthorizedServicesApiControllerBase : UmbracoApiController
10+
{
11+
public AuthorizedServicesApiControllerBase(IAuthorizedServiceCaller authorizedServiceCaller) => AuthorizedServiceCaller = authorizedServiceCaller;
12+
13+
protected IAuthorizedServiceCaller AuthorizedServiceCaller { get; }
14+
15+
protected IActionResult HandleFailedRequest(Exception? exception, string defaultMessage)
16+
{
17+
if (exception is not null)
18+
{
19+
if (exception is AuthorizedServiceHttpException authorizedServiceHttpException)
20+
{
21+
if (authorizedServiceHttpException.StatusCode == HttpStatusCode.NotFound)
22+
{
23+
return NotFound();
24+
}
25+
26+
return StatusCode((int)authorizedServiceHttpException.StatusCode, authorizedServiceHttpException.Reason + ": " + authorizedServiceHttpException.Content);
27+
}
28+
29+
if (exception is AuthorizedServiceException authorizedServiceException)
30+
{
31+
return StatusCode((int)HttpStatusCode.InternalServerError, authorizedServiceException.Message);
32+
}
33+
34+
return StatusCode((int)HttpStatusCode.InternalServerError, exception.Message);
35+
}
36+
37+
return StatusCode((int)HttpStatusCode.InternalServerError, defaultMessage);
38+
}
39+
}

examples/Umbraco.AuthorizedServices.TestSite/Controllers/HubspotContactsController.cs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,33 @@
33
using Umbraco.AuthorizedServices.Services;
44
using Umbraco.AuthorizedServices.TestSite.Models.Dtos;
55
using Umbraco.AuthorizedServices.TestSite.Models.ServiceResponses;
6-
using Umbraco.Cms.Web.Common.Controllers;
6+
using Umbraco.Cms.Core;
77

88
namespace Umbraco.AuthorizedServices.TestSite.Controllers;
99

1010
[Route("umbraco/authorizedservice/hubspot/v1/contacts")]
11-
public class HubspotContactsController : UmbracoApiController
11+
public class HubspotContactsController : AuthorizedServicesApiControllerBase
1212
{
1313
private const string ServiceAlias = "hubspot";
1414
private const string BasePath = "/crm/v3/objects/contacts/";
1515

16-
private readonly IAuthorizedServiceCaller _authorizedServiceCaller;
17-
18-
public HubspotContactsController(IAuthorizedServiceCaller authorizedServiceCaller) => _authorizedServiceCaller = authorizedServiceCaller;
16+
public HubspotContactsController(IAuthorizedServiceCaller authorizedServiceCaller)
17+
: base(authorizedServiceCaller)
18+
{
19+
}
1920

2021
[HttpGet]
2122
public async Task<IActionResult> Get()
2223
{
23-
HubspotContactResponse? response = await _authorizedServiceCaller.GetRequestAsync<HubspotContactResponse>(
24+
Attempt<HubspotContactResponse?> responseAttempt = await AuthorizedServiceCaller.GetRequestAsync<HubspotContactResponse>(
2425
ServiceAlias,
2526
BasePath);
26-
if (response == null)
27+
if (!responseAttempt.Success || responseAttempt.Result is null)
2728
{
28-
return Problem("Could not retrieve contacts.");
29+
return HandleFailedRequest(responseAttempt.Exception, "Could not retrieve contacts.");
2930
}
3031

32+
HubspotContactResponse response = responseAttempt.Result;
3133
return Ok(
3234
response.Results
3335
.Select(MapToDto)
@@ -38,60 +40,64 @@ public async Task<IActionResult> Get()
3840
[Route("{id}")]
3941
public async Task<IActionResult> Get(string id)
4042
{
41-
HubspotContactResponse.Result? response = await _authorizedServiceCaller.GetRequestAsync<HubspotContactResponse.Result>(
43+
Attempt<HubspotContactResponse.Result?> responseAttempt = await AuthorizedServiceCaller.GetRequestAsync<HubspotContactResponse.Result>(
4244
ServiceAlias,
4345
$"{BasePath}{id}");
44-
if (response == null)
46+
47+
if (!responseAttempt.Success || responseAttempt.Result is null)
4548
{
46-
return NotFound();
49+
return HandleFailedRequest(responseAttempt.Exception, "Could not retrieve contact.");
4750
}
4851

52+
HubspotContactResponse.Result response = responseAttempt.Result;
4953
return Ok(MapToDto(response));
5054
}
5155

5256
[HttpPost]
5357
public async Task<IActionResult> Create([FromBody] ContactDto contact)
5458
{
55-
HubspotContactResponse.Result? response = await _authorizedServiceCaller.PostRequestAsync<HubspotContactResponse.Result, HubspotContactResponse.Result>(
59+
Attempt<HubspotContactResponse.Result?> responseAttempt = await AuthorizedServiceCaller.PostRequestAsync<HubspotContactResponse.Result, HubspotContactResponse.Result>(
5660
ServiceAlias,
5761
BasePath,
5862
MapToRequest(contact));
59-
if (response == null)
63+
if (!responseAttempt.Success || responseAttempt.Result is null)
6064
{
61-
return Problem("Could not create contact.");
65+
return HandleFailedRequest(responseAttempt.Exception, "Could not create contact.");
6266
}
6367

68+
HubspotContactResponse.Result response = responseAttempt.Result;
6469
return CreatedAtAction(nameof(Get), new { id = response.Id }, MapToDto(response));
6570
}
6671

6772
[HttpPut]
6873
public async Task<IActionResult> Update([FromBody] ContactDto contact)
6974
{
70-
HubspotContactResponse.Result? response = await _authorizedServiceCaller.PatchRequestAsync<HubspotContactResponse.Result, HubspotContactResponse.Result>(
75+
Attempt<HubspotContactResponse.Result?> responseAttempt = await AuthorizedServiceCaller.PatchRequestAsync<HubspotContactResponse.Result, HubspotContactResponse.Result>(
7176
ServiceAlias,
7277
$"{BasePath}{contact.Id}",
7378
MapToRequest(contact));
74-
if (response == null)
79+
if (!responseAttempt.Success || responseAttempt.Result is null)
7580
{
76-
return Problem("Could not update contact.");
81+
return HandleFailedRequest(responseAttempt.Exception, "Could not update contact.");
7782
}
7883

84+
HubspotContactResponse.Result response = responseAttempt.Result;
7985
return Ok(MapToDto(response));
8086
}
8187

8288
[HttpDelete]
8389
[Route("{id}")]
8490
public async Task<IActionResult> Delete(string id)
8591
{
86-
await _authorizedServiceCaller.DeleteRequestAsync(
92+
await AuthorizedServiceCaller.DeleteRequestAsync(
8793
ServiceAlias,
8894
$"{BasePath}{id}");
8995

9096
return NoContent();
9197
}
9298

9399
private ContactDto MapToDto(HubspotContactResponse.Result result) =>
94-
new ContactDto
100+
new()
95101
{
96102
Id = result.Id,
97103
FirstName = result.Properties.FirstName,
@@ -100,7 +106,7 @@ private ContactDto MapToDto(HubspotContactResponse.Result result) =>
100106
};
101107

102108
private HubspotContactResponse.Result MapToRequest(ContactDto dto) =>
103-
new HubspotContactResponse.Result
109+
new()
104110
{
105111
Id = dto.Id,
106112
Properties = new HubspotContactResponse.ResultProperties

0 commit comments

Comments
 (0)