存取遠端資料
注意
本電子書於 2017 年春季出版,此後尚未更新。 這本書中有很多仍然有價值的,但一些材料已經過時。
許多現代化 Web 型解決方案利用網頁伺服器代管的 Web 服務來提供遠端用戶端應用程式所需功能。 Web 服務公開的作業會構成 Web API。
用戶端應用程式應能夠利用此 Web API,而不需要知道 API 所公開資料或作業的實作方式。 若要達到這個目標,API 必須遵守促使用戶端應用程式和 Web 服務就使用之資料格式,以及用戶端應用程式和 Web 服務兩者交換之資料結構等取得共識的通用標準。
具象狀態傳輸簡介
具象狀態傳輸 (REST) 是一種架構樣式,可建置以超媒體為基礎的分散式系統。 REST 模型的主要優點是基於開放標準,而能避免模型實作或存取模型的用戶端應用程式受到任何特定實作約束。 因此,REST Web 服務可以使用 Microsoft ASP.NET Core MVC 來實作,而用戶端應用程式可以使用任何可產生 HTTP 要求和剖析 HTTP 回應的語言和工具組進行開發。
REST 模型使用瀏覽配置來透過網路呈現物件和服務 (稱為「資源」)。 實作 REST 的系統通常會使用 HTTP 通訊協定來傳送這些資源的存取要求。 在這類系統中,用戶端應用程式會以識別資源的 URI 形式提交要求,以及指出要在該資源上執行作業的 HTTP 方法 (例如 GET、POST、PUT 或 DELETE)。 HTTP 要求的本文包含執行作業所需的任何資料。
注意
REST 會定義無狀態要求模型。 因此,HTTP 要求必須獨立,且可能會依任何順序發生。
來自 REST 要求的回應會使用標準 HTTP 狀態碼。 例如,傳回有效數據的要求應該包含 HTTP 回應碼 200 (確定),而找不到或刪除指定資源的要求應該傳回包含 HTTP 狀態代碼 404 (找不到) 的回應。
RESTful Web API 會公開一組連線的資源,並提供讓應用程式操作這些資源及輕易地在之間瀏覽的核心作業。 基於這個理由,構成典型 RESTful Web API 的 URI 會以其所公開的資料為導向,並使用 HTTP 所提供的機制來操作這些資料。
用戶端應用程式加入 HTTP 要求中的資料,以及來自網頁伺服器的對應回應訊息,都能以各種不同的格式來呈現 (稱為「媒體類型」)。 當用戶端應用程式傳送傳回訊息本文中數據的要求時,它可以指定可在要求標頭中 Accept
處理的媒體類型。 如果網頁伺服器支援此媒體類型,它可以以包含 Content-Type
標頭的回應來回復,該回應會指定訊息本文中的數據格式。 接著用戶端應用程式必須負責剖析回應訊息,並適當地解譯訊息本文中的結果。
如需 REST 的詳細資訊,請參閱 API 設計和 API 實作。
使用 RESTful API
eShopOnContainers 行動應用程式會使用 Model-View-ViewModel (MVVM) 模式,而模式的模型元素代表應用程式中使用的領域實體。 eShopOnContainers 參考應用程式中的控制器和存放庫類別會接受並傳回其中許多模型物件。 因此,它們會用來作為數據傳輸物件(DTO),以保存在行動應用程式與容器化微服務之間傳遞的所有數據。 使用 DTO 將資料傳遞至 Web 服務並從中接收資料的主要優點是,藉由在單一遠端呼叫中傳輸更多資料,應用程式可以減少需要進行的遠端呼叫數目。
提出 Web 要求
eShopOnContainers 行動應用程式會 HttpClient
使用 類別透過 HTTP 提出要求,並將 JSON 當做媒體類型使用。 此類別提供以非同步方式將 HTTP 要求傳送至 URI 所識別資源並從中接收 HTTP 要求的功能。 類別 HttpResponseMessage
代表在提出 HTTP 要求之後,從 REST API 接收的 HTTP 回應消息。 其中包含回應的資訊,包括狀態碼、標頭和任何本文。 類別 HttpContent
代表 HTTP 主體和內容標頭,例如 Content-Type
和 Content-Encoding
。 您可以根據資料格式,使用任何 ReadAs
方法 (例如 ReadAsStringAsync
和 ReadAsByteArrayAsync
) 讀取內容。
提出 GET 要求
CatalogService
類別可用來管理目錄微服務中的資料擷取程序。 在類別 RegisterDependencies
的 方法中 ViewModelLocator
,類別 CatalogService
會向具有 Autofac 相依性插入容器的類型 ICatalogService
註冊為類型對應。 然後,建立 類別的 CatalogViewModel
實例時,其建構函式會接受 ICatalogService
Autofac 解析的類型,並傳回 類別的 CatalogService
實例。 如需相依性插入的詳細資訊,請參閱 相依性插入簡介。
圖 10-1 顯示類別的互動,這些類別會從目錄微服務讀取目錄數據,以供 顯示 CatalogView
。
圖 10-1:從目錄微服務擷取數據
CatalogView
巡覽至 時,OnInitialize
會呼叫 類別中的 CatalogViewModel
方法。 此方法會從目錄微服務擷取目錄資料,如下列程式碼範例所示:
public override async Task InitializeAsync(object navigationData)
{
...
Products = await _productsService.GetCatalogAsync();
...
}
這個方法會呼叫 GetCatalogAsync
Autofac 所插入 CatalogViewModel
實例的 CatalogService
方法。 下列程式碼範例示範 GetCatalogAsync
方法:
public async Task<ObservableCollection<CatalogItem>> GetCatalogAsync()
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
builder.Path = "api/v1/catalog/items";
string uri = builder.ToString();
CatalogRoot catalog = await _requestProvider.GetAsync<CatalogRoot>(uri);
...
return catalog?.Data.ToObservableCollection();
}
此方法會建立 URI 以識別將收到要求的資源,並使用 RequestProvider
類別在資源上叫用 GET HTTP 方法,再將結果傳回給 CatalogViewModel
。 RequestProvider
類別包含的功能可讓您以識別資源的 URI 形式提交要求、指出要在該資源上執行作業的 HTTP 方法,以及包含執行作業所需任何資料的本文。 如需如何將 RequestProvider
類別插入 CatalogService class
的資訊,請參閱 相依性插入簡介。
下列程式碼範例顯示 RequestProvider
類別中的 GetAsync
方法:
public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
HttpClient httpClient = CreateHttpClient(token);
HttpResponseMessage response = await httpClient.GetAsync(uri);
await HandleResponse(response);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = await Task.Run(() =>
JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));
return result;
}
此方法會呼叫 CreateHttpClient
方法,再由其傳回具有適當標頭集的 HttpClient
類別執行個體。 然後,它會將異步 GET 要求提交至 URI 所識別的資源,並將回應儲存在 實例中 HttpResponseMessage
。 接著會叫用 HandleResponse
方法,如果回應未包含成功 HTTP 狀態碼,則會擲回例外狀況。 然後,回應會讀取為字串、從 JSON 轉換成 CatalogRoot
物件,再傳回給 CatalogService
。
CreateHttpClient
方法如下列程式碼範例所示:
private HttpClient CreateHttpClient(string token = "")
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
if (!string.IsNullOrEmpty(token))
{
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
}
return httpClient;
}
這個方法會建立 類別的新實例HttpClient
,並將 實例所HttpClient
提出之任何要求的標頭設定Accept
為 application/json
,表示它預期任何回應的內容會使用 JSON 格式化。 然後,如果將存取權杖當作引數傳遞至 CreateHttpClient
方法,就會新增至 HttpClient
執行個體所提交任何要求的 Authorization
標頭,並在前面加上字串 Bearer
。 如需授權的詳細資訊,請參閱授權。
GetAsync
當類別中的 RequestProvider
方法呼叫 HttpClient.GetAsync
時,Items
會叫用 Catalog.API 項目中 類別中的 方法CatalogController
,如下列程式代碼範例所示:
[HttpGet]
[Route("[action]")]
public async Task<IActionResult> Items(
[FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
{
var totalItems = await _catalogContext.CatalogItems
.LongCountAsync();
var itemsOnPage = await _catalogContext.CatalogItems
.OrderBy(c=>c.Name)
.Skip(pageSize * pageIndex)
.Take(pageSize)
.ToListAsync();
itemsOnPage = ComposePicUri(itemsOnPage);
var model = new PaginatedItemsViewModel<CatalogItem>(
pageIndex, pageSize, totalItems, itemsOnPage);
return Ok(model);
}
這個方法會使用 EntityFramework 從 SQL 資料庫擷取目錄數據,並將它當做回應訊息傳回,其中包含成功的 HTTP 狀態代碼,以及 JSON 格式化 CatalogItem
實例的集合。
提出POST要求
BasketService
類別可用來管理購物籃微服務的資料擷取和更新程序。 在類別 RegisterDependencies
的 方法中 ViewModelLocator
,類別 BasketService
會向具有 Autofac 相依性插入容器的類型 IBasketService
註冊為類型對應。 然後,建立 類別的 BasketViewModel
實例時,其建構函式會接受 IBasketService
Autofac 解析的類型,並傳回 類別的 BasketService
實例。 如需相依性插入的詳細資訊,請參閱 相依性插入簡介。
圖 10-2 顯示類別的互動,這些類別會將 所 BasketView
顯示的購物籃數據傳送至購物籃微服務。
圖 10-2:將數據傳送至購物籃微服務
將項目新增至購物籃時,會呼叫 BasketViewModel
類別中的 ReCalculateTotalAsync
方法。 此方法會更新購物籃中項目的總計值,並將購物籃資料傳送至購物籃微服務,如下列程式碼範例所示:
private async Task ReCalculateTotalAsync()
{
...
await _basketService.UpdateBasketAsync(new CustomerBasket
{
BuyerId = userInfo.UserId,
Items = BasketItems.ToList()
}, authToken);
}
這個方法會呼叫 UpdateBasketAsync
Autofac 所插入 BasketViewModel
實例的 BasketService
方法。 下列方法會顯示 UpdateBasketAsync
方法:
public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket customerBasket, string token)
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint);
string uri = builder.ToString();
var result = await _requestProvider.PostAsync(uri, customerBasket, token);
return result;
}
此方法會建立 URI 以識別將收到要求的資源,並使用 RequestProvider
類別在資源上叫用 POST HTTP 方法,再將結果傳回給 BasketViewModel
。 請注意,必須在驗證程序期間從 IdentityServer 取得存取令牌,才能授權對購物籃微服務的要求。 如需授權的詳細資訊,請參閱授權。
下列程式碼範例顯示 RequestProvider
類別中的其中一個 PostAsync
方法:
public async Task<TResult> PostAsync<TResult>(
string uri, TResult data, string token = "", string header = "")
{
HttpClient httpClient = CreateHttpClient(token);
...
var content = new StringContent(JsonConvert.SerializeObject(data));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = await httpClient.PostAsync(uri, content);
await HandleResponse(response);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = await Task.Run(() =>
JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));
return result;
}
此方法會呼叫 CreateHttpClient
方法,再由其傳回具有適當標頭集的 HttpClient
類別執行個體。 然後會將非同步 POST 要求提交至 URI 所識別的資源,以 JSON 格式傳送序列化的購物籃資料,並將回應儲存在 HttpResponseMessage
執行個體中。 接著會叫用 HandleResponse
方法,如果回應未包含成功 HTTP 狀態碼,則會擲回例外狀況。 然後,回應會讀取為字串,從 JSON CustomerBasket
轉換成 物件,並傳回至 BasketService
。 如需 方法的詳細資訊 CreateHttpClient
,請參閱 提出 GET 要求。
PostAsync
當類別中的 RequestProvider
方法呼叫 HttpClient.PostAsync
時,Post
會叫用Basket.API專案中類別中的方法BasketController
,如下列程式代碼範例所示:
[HttpPost]
public async Task<IActionResult> Post([FromBody]CustomerBasket value)
{
var basket = await _repository.UpdateBasketAsync(value);
return Ok(basket);
}
此方法會使用 RedisBasketRepository
類別的執行個體,將購物籃資料保存至 Redis 快取,並當作回應訊息傳回,其中包含成功 HTTP 狀態碼,以及 JSON 格式的 CustomerBasket
執行個體。
提出 DELETE 要求
圖 10-3 顯示 類別的互動,這些類別會針對 CheckoutView
從購物籃微服務中刪除購物籃數據。
圖 10-3:從購物籃微服務刪除數據
叫用結帳程序時,會呼叫 CheckoutViewModel
類別中的 CheckoutAsync
方法。 此方法會在清除購物籃之前建立新的訂單,如下列程式碼範例所示:
private async Task CheckoutAsync()
{
...
await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);
...
}
這個方法會呼叫 ClearBasketAsync
Autofac 所插入 CheckoutViewModel
實例的 BasketService
方法。 下列方法顯示 ClearBasketAsync
方法:
public async Task ClearBasketAsync(string guidUser, string token)
{
UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint);
builder.Path = guidUser;
string uri = builder.ToString();
await _requestProvider.DeleteAsync(uri, token);
}
這個方法會建置 URI,以識別將傳送要求的資源,並使用 類別在資源上叫用 RequestProvider
DELETE HTTP 方法。 請注意,必須在驗證程序期間從 IdentityServer 取得存取令牌,才能授權對購物籃微服務的要求。 如需授權的詳細資訊,請參閱授權。
下列程式碼範例顯示 RequestProvider
類別中的 DeleteAsync
方法:
public async Task DeleteAsync(string uri, string token = "")
{
HttpClient httpClient = CreateHttpClient(token);
await httpClient.DeleteAsync(uri);
}
此方法會呼叫 CreateHttpClient
方法,再由其傳回具有適當標頭集的 HttpClient
類別執行個體。 然後,它會將異步 DELETE 要求提交至 URI 所識別的資源。 如需 方法的詳細資訊 CreateHttpClient
,請參閱 提出 GET 要求。
DeleteAsync
當類別中的 RequestProvider
方法呼叫 HttpClient.DeleteAsync
時,Delete
會叫用Basket.API專案中類別中的方法BasketController
,如下列程式代碼範例所示:
[HttpDelete("{id}")]
public void Delete(string id)
{
_repository.DeleteBasketAsync(id);
}
此方法會使用 RedisBasketRepository
類別的執行個體,從 Redis 快取刪除購物籃資料。
快取資料
藉由將經常存取的資料快取至位置接近應用程式的快速儲存體,即可改善應用程式的效能。 如果快速儲存體的位置比原始來源更接近應用程式,則快取可大幅改善擷取資料時的回應時間。
最常見的快取形式是直接讀取快取,其中應用程式會透過參考快取來擷取資料。 如果資料不在快取中,就會從資料存放區擷取,並加入快取。 應用程式可以使用另行快取模式來實作直接讀取快取。 此模式會判斷項目目前是否在快取中。 如果項目不在快取中,就會從資料存放區讀取,並新增至快取。 如需詳細資訊,請參閱 Cache-Aside 模式。
提示
快取經常讀取且不常變更的數據。 此資料會在應用程式第一次擷取時隨選新增至快取。 這表示應用程式僅需從資料存放區擷取一次資料,而後續存取可透過使用快取來滿足。
分散式應用程式 (例如 eShopOnContainers 參考應用程式) 應提供下列其中一或兩個快取:
- 共用快取,可由多個處理序或電腦存取。
- 私用快取,其中資料會保留在執行應用程式的裝置本機上。
eShopOnContainers 行動應用程式會使用私人快取,其中數據會保留在執行應用程式實例的裝置本機上。 如需 eShopOnContainers 參考應用程式所使用的快取資訊,請參閱 .NET 微服務:容器化 .NET 應用程式的架構。
提示
請將快取視為可能會隨時消失的暫時性資料存放區。 請確定資料會同時保留在原始資料存放區及快取中。 如果快取無法使用,就能將遺失資料的機率降到最低。
管理數據到期日
期望快取的資料始終與原始資料一致並不實際。 原始資料存放區中的資料可能會在快取後變更,並造成快取的資料過時。 因此,應用程式應該實作的策略是,協助確保快取中的資料盡可能保持最新,也可以偵測並處理當快取中的資料變成過時的情況。 大多數快取機制都可讓您設定快取的資料到期,因此減少資料可能過期的期間。
提示
請在設定快取時,設定預設到期時間。 許多快取實作的到期是,如果資料在指定的期間內沒有被存取過,就會讓資料無效並從快取移除。 不過,選擇到期時間時,請務必小心。 如果太短,資料將會太快到期,而使快取的優點大打折扣。 如果太長,資料就有過時的風險。 因此,到期時間應該符合使用資料之應用程式的存取模式。
當快取的資料到期時,應該從快取予以移除,且應用程式必須從原始資料存放區擷取資料,並將其放回快取中。
如果允許保留資料的時間太長,則快取也可能會填滿。 因此,將新項目加入快取的要求可能必須在稱為「收回」的程序中移除某些項目。 快取服務通常會根據「最近最少使用」原則來收回資料。 不過,還有其他收回原則,包括最近使用的和先出先出。如需詳細資訊,請參閱 快取指引。
快取影像
eShopOnContainers 行動應用程式會取用受益於快取的遠端產品映像。 這些影像會由 Image
控件顯示,以及 CachedImage
FFImageLoading 連結庫所提供的控件。
控件 Xamarin.FormsImage
支援快取下載的映像。 默認會啟用快取,並將映像儲存在本機 24 小時。 此外,可以使用 屬性來設定 CacheValidity
到期時間。 如需詳細資訊,請參閱 下載的映像快取。
FFImageLoading 的控件是控制件的 CachedImage
取代 Xamarin.FormsImage
專案,提供可啟用補充功能的其他屬性。 在這項功能中,控件提供可設定的快取,同時支援錯誤和載入影像佔位元。 下列程式代碼範例示範 eShopOnContainers 行動應用程式CachedImage
如何使用 中的 ProductTemplate
控件,這是 控件在 中使用的CatalogView
數據範本ListView
:
<ffimageloading:CachedImage
Grid.Row="0"
Source="{Binding PictureUri}"
Aspect="AspectFill">
<ffimageloading:CachedImage.LoadingPlaceholder>
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="default_campaign" />
<On Platform="UWP" Value="Assets/default_campaign.png" />
</OnPlatform>
</ffimageloading:CachedImage.LoadingPlaceholder>
<ffimageloading:CachedImage.ErrorPlaceholder>
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="noimage" />
<On Platform="UWP" Value="Assets/noimage.png" />
</OnPlatform>
</ffimageloading:CachedImage.ErrorPlaceholder>
</ffimageloading:CachedImage>
控件會將 CachedImage
LoadingPlaceholder
和 ErrorPlaceholder
屬性設定為平臺特定的映像。 屬性 LoadingPlaceholder
會指定要在擷取屬性所 Source
指定影像時所顯示的影像,而 ErrorPlaceholder
屬性會指定要在嘗試擷取 屬性所 Source
指定影像時發生錯誤時所要顯示的影像。
顧名思義,控件會 CachedImage
快取裝置上的遠端映像,以取得 屬性的值 CacheDuration
所指定的時間。 如果未明確設定這個屬性值,則會套用預設值 30 天。
增加復原能力
與遠端服務和資源進行通訊的所有應用程式必須能感應暫時性錯誤。 暫時性錯誤包括瞬間失去服務的網路連線、暫時無法使用服務,或當服務忙碌時逾時。 這些錯誤通常會自行修正,如果在適當的延遲後再重複此動作,可能會成功。
暫時性錯誤可能會對應用程式的認知品質造成重大影響,即使應用程式已在所有可預測狀況下經過徹底的檢查也一樣。 為了確保與遠端服務通訊的應用程式能夠可靠地運作,其必須要能執行下列所有作業:
- 在錯誤發生時偵測到錯誤,並判斷錯誤是否可能是暫時性。
- 如果經判定錯誤可能是暫時性,則重試作業,並追蹤作業重試的次數。
- 使用適當的重試策略,指定重試次數、每次嘗試之間延遲的時間,以及嘗試失敗後採取的動作。
此暫時性錯誤處理可透過將存取遠端服務的所有嘗試包裝在實作重試模式的程式碼中來達成。
重試模式
如果應用程式嘗試將要求傳送至遠端服務時偵測到失敗,則可以透過下列任何方式來處理失敗:
- 重試作業。 應用程式可以立即重試失敗的要求。
- 延遲後重試作業。 應用程式應等待一段適當的時間後再重試要求。
- 取消作業。 應用程式應取消作業並報告例外狀況。
重試策略應該加以調整以符合應用程式的商務需求。 例如,請務必根據要嘗試的作業來最佳化重試計數和重試間隔。 如果作業是使用者互動的一部分,則重試間隔應該很短,且只會重試幾次,以避免讓使用者等待回應。 如果作業是長期執行工作流程的一部分,由於取消或重新開始工作流程不是很昂貴就是很耗時,因此嘗試之間的等待時間適合較長,也適合重試更多次。
注意
積極的重試策略在嘗試之間有最短的延遲,而大量重試的結果,可能會讓即將達到或已達容量的遠端服務效能下降。 此外,如果持續嘗試執行失敗的作業,這類重試策略也可能會影響應用程式的回應能力。
如果在大量重試之後要求仍失敗,最好避免應用程式再向相同資源提出要求,並回報失敗。 然後,在一定時間後,應用程式可以對資源提出一或多個要求,看看是否會成功。 如需詳細資訊,請參閱 斷路器模式。
提示
永不實作無止盡的重試機制。 請限制重試次數,或實作斷路器模式以允許服務復原。
eShopOnContainers 行動應用程式目前不會在提出 RESTful Web 要求時實作重試模式。 不過,CachedImage
FFImageLoading 連結庫提供的 控件可藉由重試影像載入來支持暫時性錯誤處理。 如果影像載入失敗,將會進行進一步的嘗試。 屬性會 RetryCount
指定嘗試次數,而且會在屬性指定的 RetryDelay
延遲之後重試。 如果未明確設定這些屬性值,則會套 RetryCount
用其預設值 – 屬性的預設值為 3,而 屬性會 RetryDelay
套用 250 毫秒。 如需控件的詳細資訊 CachedImage
,請參閱 快取映像。
eShopOnContainers 參考應用程式會實作重試模式。 如需詳細資訊,包括如何結合重試模式與 HttpClient
類別的討論,請參閱 .NET 微服務:容器化 .NET 應用程式的架構。
如需重試模式的詳細資訊,請參閱 重試 模式。
斷路器模式
在某些情況下,可能會因花太長時間修正的預期事件而發生錯誤。 這些錯誤可能從失去部分連線到服務完全失敗都包括在內。 在這些情況下,讓應用程式重試不太可能成功的作業是無意義的;相反地,應快速接受作業失敗,並據以處理此失敗。
斷路器模式可防止應用程式重複嘗試執行可能失敗的作業,同時讓應用程式偵測是否已解決錯誤。
注意
斷路器模式的目的與重試模式不同。 重試模式會在預期作業會成功的情況下,讓應用程式重試作業。 斷路器模式可防止應用程式執行可能失敗的作業。
斷路器可作為可能失敗之作業的 Proxy。 Proxy 應監視最近發生的失敗次數,並使用這項資訊來決定是允許作業繼續,還是立即傳回例外狀況。
eShopOnContainers 行動應用程式目前不會實作斷路器模式。 不過,eShopOnContainers 已實作。 如需詳細資訊,請參閱 .NET 微服務:容器化 .NET 應用程式的架構。
提示
結合重試模式與斷路器模式。 應用程式可以使用重試模式透過斷路器來叫用作業,以結合重試模式與斷路器模式。 不過,重試邏輯應該會受到斷路器所傳回之任何例外狀況的影響,而且如果斷路器指出錯誤不是暫時的,就應該放棄重試嘗試。
如需斷路器模式的詳細資訊,請參閱 斷路器 模式。
摘要
許多現代化 Web 型解決方案利用網頁伺服器代管的 Web 服務來提供遠端用戶端應用程式所需功能。 Web 服務所公開的作業會構成 Web API,用戶端應用程式應能夠利用此 Web API,而不需要知道 API 所公開資料或作業的實作方式。
藉由將經常存取的資料快取至位置接近應用程式的快速儲存體,即可改善應用程式的效能。 應用程式可以使用另行快取模式來實作直接讀取快取。 此模式會判斷項目目前是否在快取中。 如果項目不在快取中,就會從資料存放區讀取,並新增至快取。
使用 Web API 進行通訊時,應用程式必須能感應暫時性錯誤。 暫時性錯誤包括瞬間失去服務的網路連線、暫時無法使用服務,或當服務忙碌時逾時。 這些錯誤通常會自行修正,如果在適當的延遲後再重複此動作,則可能會成功。 因此,應用程式應該將存取 Web API 的所有嘗試包裝在實作暫時性錯誤處理機制的程式碼中。