Refactoing HttpClientApi

This commit is contained in:
Ramón Tomás 2017-03-17 13:12:34 +01:00
parent cb3f682872
commit ddb03a0aa8
8 changed files with 87 additions and 24 deletions

View File

@ -14,15 +14,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public class BasketService : IBasketService public class BasketService : IBasketService
{ {
private readonly IOptionsSnapshot<AppSettings> _settings; private readonly IOptionsSnapshot<AppSettings> _settings;
private HttpClientWrapper _apiClient; private IHttpClient _apiClient;
private readonly string _remoteServiceBaseUrl; private readonly string _remoteServiceBaseUrl;
private IHttpContextAccessor _httpContextAccesor; private IHttpContextAccessor _httpContextAccesor;
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor) public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
{ {
_settings = settings; _settings = settings;
_remoteServiceBaseUrl = _settings.Value.BasketUrl; _remoteServiceBaseUrl = _settings.Value.BasketUrl;
_httpContextAccesor = httpContextAccesor; _httpContextAccesor = httpContextAccesor;
_apiClient = httpClient;
} }
public async Task<Basket> GetBasket(ApplicationUser user) public async Task<Basket> GetBasket(ApplicationUser user)
@ -30,7 +31,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
var _apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}"; var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}";
@ -51,8 +51,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = _remoteServiceBaseUrl; var basketUrl = _remoteServiceBaseUrl;
@ -119,7 +118,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}"; var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id.ToString()}";
var response = await _apiClient.DeleteAsync(basketUrl); var response = await _apiClient.DeleteAsync(basketUrl);

View File

@ -13,20 +13,19 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public class CatalogService : ICatalogService public class CatalogService : ICatalogService
{ {
private readonly IOptionsSnapshot<AppSettings> _settings; private readonly IOptionsSnapshot<AppSettings> _settings;
private HttpClientWrapper _apiClient; private IHttpClient _apiClient;
private readonly string _remoteServiceBaseUrl; private readonly string _remoteServiceBaseUrl;
public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory) { public CatalogService(IOptionsSnapshot<AppSettings> settings, ILoggerFactory loggerFactory, IHttpClient httpClient) {
_settings = settings; _settings = settings;
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/"; _remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
_apiClient = httpClient;
var log = loggerFactory.CreateLogger("catalog service"); var log = loggerFactory.CreateLogger("catalog service");
log.LogDebug(settings.Value.CatalogUrl); log.LogDebug(settings.Value.CatalogUrl);
} }
public async Task<Catalog> GetCatalogItems(int page,int take, int? brand, int? type) public async Task<Catalog> GetCatalogItems(int page,int take, int? brand, int? type)
{ {
_apiClient = new HttpClientWrapper();
var itemsQs = $"items?pageIndex={page}&pageSize={take}"; var itemsQs = $"items?pageIndex={page}&pageSize={take}";
var filterQs = ""; var filterQs = "";
@ -53,7 +52,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public async Task<IEnumerable<SelectListItem>> GetBrands() public async Task<IEnumerable<SelectListItem>> GetBrands()
{ {
_apiClient = new HttpClientWrapper();
var url = $"{_remoteServiceBaseUrl}catalogBrands"; var url = $"{_remoteServiceBaseUrl}catalogBrands";
var dataString = await _apiClient.GetStringAsync(url); var dataString = await _apiClient.GetStringAsync(url);
@ -72,7 +70,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public async Task<IEnumerable<SelectListItem>> GetTypes() public async Task<IEnumerable<SelectListItem>> GetTypes()
{ {
_apiClient = new HttpClientWrapper();
var url = $"{_remoteServiceBaseUrl}catalogTypes"; var url = $"{_remoteServiceBaseUrl}catalogTypes";
var dataString = await _apiClient.GetStringAsync(url); var dataString = await _apiClient.GetStringAsync(url);

View File

@ -14,24 +14,23 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{ {
public class OrderingService : IOrderingService public class OrderingService : IOrderingService
{ {
private HttpClientWrapper _apiClient; private IHttpClient _apiClient;
private readonly string _remoteServiceBaseUrl; private readonly string _remoteServiceBaseUrl;
private readonly IOptionsSnapshot<AppSettings> _settings; private readonly IOptionsSnapshot<AppSettings> _settings;
private readonly IHttpContextAccessor _httpContextAccesor; private readonly IHttpContextAccessor _httpContextAccesor;
public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor) public OrderingService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
{ {
_remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders";
_settings = settings; _settings = settings;
_httpContextAccesor = httpContextAccesor; _httpContextAccesor = httpContextAccesor;
_apiClient = httpClient;
} }
async public Task<Order> GetOrder(ApplicationUser user, string Id) async public Task<Order> GetOrder(ApplicationUser user, string Id)
{ {
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}"; var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}";
@ -47,7 +46,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var ordersUrl = _remoteServiceBaseUrl; var ordersUrl = _remoteServiceBaseUrl;
@ -78,7 +76,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var context = _httpContextAccesor.HttpContext; var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token"); var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient = new HttpClientWrapper();
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); _apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
_apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString()); _apiClient.Inst.DefaultRequestHeaders.Add("x-requestid", order.RequestId.ToString());

View File

@ -0,0 +1,45 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace WebMVC.Services.Utilities
{
public class HttpApiClient : IHttpClient
{
private HttpClient _client;
private ILogger _logger;
public HttpClient Inst => _client;
public HttpApiClient()
{
_client = new HttpClient();
_logger = new LoggerFactory().CreateLogger(nameof(HttpApiClientWrapper));
}
public async Task<string> GetStringAsync(string uri)
{
return await HttpInvoker(async () =>
await _client.GetStringAsync(uri));
}
public async Task<HttpResponseMessage> PostAsync<T>(string uri, T item)
{
var contentString = new StringContent(JsonConvert.SerializeObject(item), System.Text.Encoding.UTF8, "application/json");
return await HttpInvoker(async () =>
await _client.PostAsync(uri, contentString));
}
public async Task<HttpResponseMessage> DeleteAsync(string uri)
{
return await HttpInvoker(async () =>
await _client.DeleteAsync(uri));
}
private async Task<T> HttpInvoker<T>(Func<Task<T>> action)
{
return await action();
}
}
}

View File

@ -8,16 +8,16 @@ using System.Threading.Tasks;
namespace WebMVC.Services.Utilities namespace WebMVC.Services.Utilities
{ {
public class HttpClientWrapper public class HttpApiClientWrapper : IHttpClient
{ {
private HttpClient _client; private HttpClient _client;
private PolicyWrap _policyWrapper; private PolicyWrap _policyWrapper;
private ILogger _logger; private ILogger _logger;
public HttpClient Inst => _client; public HttpClient Inst => _client;
public HttpClientWrapper() public HttpApiClientWrapper()
{ {
_client = new HttpClient(); _client = new HttpClient();
_logger = new LoggerFactory().CreateLogger(nameof(HttpClientWrapper)); _logger = new LoggerFactory().CreateLogger(nameof(HttpApiClientWrapper));
// Add Policies to be applied // Add Policies to be applied
_policyWrapper = Policy.WrapAsync( _policyWrapper = Policy.WrapAsync(

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace WebMVC.Services.Utilities
{
public interface IHttpClient
{
HttpClient Inst { get; }
Task<string> GetStringAsync(string uri);
Task<HttpResponseMessage> PostAsync<T>(string uri, T item);
Task<HttpResponseMessage> DeleteAsync(string uri);
}
}

View File

@ -14,6 +14,7 @@ using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using System.Threading; using System.Threading;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using WebMVC.Services.Utilities;
namespace Microsoft.eShopOnContainers.WebMVC namespace Microsoft.eShopOnContainers.WebMVC
{ {
@ -43,14 +44,22 @@ namespace Microsoft.eShopOnContainers.WebMVC
{ {
services.AddMvc(); services.AddMvc();
services.Configure<AppSettings>(Configuration); services.Configure<AppSettings>(Configuration);
// Add application services. // Add application services.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<ICatalogService, CatalogService>(); services.AddTransient<ICatalogService, CatalogService>();
services.AddTransient<IOrderingService, OrderingService>(); services.AddTransient<IOrderingService, OrderingService>();
services.AddTransient<IBasketService, BasketService>(); services.AddTransient<IBasketService, BasketService>();
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>(); services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
if(Configuration.GetValue<string>("ActivateCircuitBreaker") == bool.TrueString)
{
services.AddSingleton<IHttpClient, HttpApiClientWrapper>();
}
else
{
services.AddSingleton<IHttpClient, HttpApiClient>();
}
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -4,6 +4,7 @@
"BasketUrl": "http://localhost:5103", "BasketUrl": "http://localhost:5103",
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",
"CallBackUrl": "http://localhost:5100/", "CallBackUrl": "http://localhost:5100/",
"ActivateCircuitBreaker": "True",
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {