Skip to content

Commit c40cc9a

Browse files
committed
Refactored IAuthorizedServiceCaller interface methods to return results within Attempt constructs.
1 parent f434466 commit c40cc9a

File tree

10 files changed

+311
-158
lines changed

10 files changed

+311
-158
lines changed

README.md

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

206206
```csharp
207-
Task<TResponse> SendRequestAsync<TResponse>(string serviceAlias, string path, HttpMethod httpMethod);
207+
Task<Attempt<TResponse?>> SendRequestAsync<TResponse>(string serviceAlias, string path, HttpMethod httpMethod);
208208
```
209209

210210
The parameters for the request are as follows:
@@ -219,7 +219,7 @@ There is also a type parameter:
219219
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:
220220

221221
```csharp
222-
Task<TResponse> SendRequestAsync<TRequest, TResponse>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
222+
Task<Attempt<TResponse>> SendRequestAsync<TRequest, TResponse>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
223223
where TRequest : class;
224224
```
225225

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

236236
```csharp
237-
Task<string> SendRequestRawAsync(string serviceAlias, string path, HttpMethod httpMethod);
237+
Task<Attempt<string?>> SendRequestRawAsync(string serviceAlias, string path, HttpMethod httpMethod);
238238

239-
Task<string> SendRequestRawAsync<TRequest>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
239+
Task<<Attempt<string?>> SendRequestRawAsync<TRequest>(string serviceAlias, string path, HttpMethod httpMethod, TRequest? requestContent = null)
240240
where TRequest : class;
241241
```
242242

243243
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.
244244

245245
```csharp
246-
Task<TResponse> GetRequestAsync<TResponse>(string serviceAlias, string path);
246+
Task<Attempt<TResponse?>> GetRequestAsync<TResponse>(string serviceAlias, string path);
247247
```
248248

249249
## 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)