Partilhar via


Acesso a dados remotos

Gorjeta

Este conteúdo é um excerto do eBook, Enterprise Application Patterns Using .NET MAUI, disponível no .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

Padrões de aplicativos corporativos usando a miniatura da capa do eBook .NET MAUI .

Muitas soluções modernas baseadas na Web fazem uso de serviços da Web, hospedados por servidores da Web, para fornecer funcionalidade para aplicativos cliente remotos. As operações que um serviço Web expõe constituem uma API Web.

Os aplicativos cliente devem ser capazes de utilizar a API da Web sem saber como os dados ou operações que a API expõe são implementados. Isso requer que a API respeite padrões comuns que permitam que um aplicativo cliente e um serviço Web concordem sobre quais formatos de dados usar e a estrutura dos dados que são trocados entre aplicativos cliente e o serviço Web.

Introdução à Transferência Representativa do Estado

Representational State Transfer (REST) é um estilo arquitetônico para a construção de sistemas distribuídos baseados em hipermídia. Uma das principais vantagens do modelo REST é que ele é baseado em padrões abertos e não vincula a implementação do modelo ou dos aplicativos cliente que o acessam a qualquer implementação específica. Portanto, um serviço Web REST pode ser implementado usando o Microsoft ASP.NET Core, e os aplicativos cliente podem ser desenvolvidos usando qualquer linguagem e conjunto de ferramentas que possam gerar solicitações HTTP e analisar respostas HTTP.

O modelo REST usa um esquema de navegação para representar objetos e serviços em uma rede, conhecidos como recursos. Os sistemas que implementam REST normalmente usam o protocolo HTTP para transmitir solicitações para acessar esses recursos. Nesses sistemas, um aplicativo cliente envia uma solicitação na forma de um URI que identifica um recurso e um método HTTP (como GET, POST, PUT ou DELETE) que indica a operação a ser executada nesse recurso. O corpo da solicitação HTTP contém todos os dados necessários para executar a operação.

Nota

REST define um modelo de solicitação sem monitoração de estado. Portanto, as solicitações HTTP devem ser independentes e podem ocorrer em qualquer ordem.

A resposta de uma solicitação REST usa códigos de status HTTP padrão. Por exemplo, uma solicitação que retorna dados válidos deve incluir o código de resposta HTTP 200 (OK), enquanto uma solicitação que não consegue localizar ou excluir um recurso especificado deve retornar uma resposta que inclua o código de status HTTP 404 (Not Found).

Uma API Web RESTful expõe um conjunto de recursos conectados e fornece as operações principais que permitem que um aplicativo manipule esses recursos e navegue facilmente entre eles. Por esse motivo, os URIs que constituem uma API da Web RESTful típica são orientados para os dados que ela expõe e usam os recursos fornecidos pelo HTTP para operar nesses dados.

Os dados incluídos por um aplicativo cliente em uma solicitação HTTP e as mensagens de resposta correspondentes do servidor Web podem ser apresentados em uma variedade de formatos, conhecidos como tipos de mídia. Quando um aplicativo cliente envia uma solicitação que retorna dados no corpo de uma mensagem, ele pode especificar os tipos de mídia que pode manipular no cabeçalho Accept da solicitação. Se o servidor Web oferecer suporte a esse tipo de mídia, ele poderá responder com uma resposta que inclua o cabeçalho Content-Type que especifica o formato dos dados no corpo da mensagem. Em seguida, é responsabilidade do aplicativo cliente analisar a mensagem de resposta e interpretar os resultados no corpo da mensagem adequadamente.

Para obter mais informações sobre REST, consulte Design de API e implementação de API no Microsoft Docs.

Consumindo APIs RESTful

O aplicativo multiplataforma eShop usa o padrão Model-View-ViewModel (MVVM) e os elementos de modelo do padrão representam as entidades de domínio usadas no aplicativo. As classes de controlador e repositório no aplicativo de referência eShop aceitam e retornam muitos desses objetos de modelo. Portanto, eles são usados como objetos de transferência de dados (DTOs) que armazenam todos os dados que são passados entre o aplicativo e os microsserviços em contêiner. O principal benefício de usar DTOs para passar e receber dados de um serviço Web é que, ao transmitir mais dados em uma única chamada remota, o aplicativo pode reduzir o número de chamadas remotas que precisam ser feitas.

Fazer pedidos na Web

O aplicativo multiplataforma eShop usa a HttpClient classe para fazer solicitações via HTTP, com JSON sendo usado como o tipo de mídia. Essa classe fornece funcionalidade para enviar solicitações HTTP de forma assíncrona e receber respostas HTTP de um recurso identificado por URI. A classe HttpResponseMessage representa uma mensagem de resposta HTTP recebida de uma API REST após uma solicitação HTTP ter sido feita. Ele contém informações sobre a resposta, incluindo o código de status, cabeçalhos e qualquer corpo. A classe HttpContent representa o corpo HTTP e os cabeçalhos de conteúdo, como Content-Type e Content-Encoding. O conteúdo pode ser lido usando qualquer um dos ReadAs métodos, como ReadAsStringAsync e ReadAsByteArrayAsync, dependendo do formato dos dados.

Fazer um pedido GET

A CatalogService classe é usada para gerenciar o processo de recuperação de dados do microsserviço de catálogo. RegisterViewModels No método na MauiProgram classe, a CatalogService classe é registrada como um mapeamento de tipo em relação ao ICatalogService tipo com o contêiner de injeção de dependência. Em seguida, quando uma instância da classe é criada, seu construtor aceita um ICatalogService type, que o contêiner de CatalogViewModel injeção de dependência resolve, retornando uma instância da CatalogService classe. Para obter mais informações sobre injeção de dependência, consulte Injeção de dependência.

A imagem abaixo mostra a interação de classes que leem dados de catálogo do microsserviço de catálogo para exibição pelo CatalogView.

Recuperando dados do microsserviço de catálogo.

Quando o CatalogView é navegado para, o OnInitialize método na classe CatalogViewModel é chamado. Esse método recupera dados de catálogo do microsserviço de catálogo, conforme demonstrado no exemplo de código a seguir:

public override async Task InitializeAsync()
{
    Products = await _productsService.GetCatalogAsync();
} 

Esse método chama o GetCatalogAsync CatalogService método da instância que foi injetada no CatalogViewModel contêiner de injeção de dependência. O exemplo de código a seguir mostra o GetCatalogAsync método:

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;          
} 

Esse método cria o URI que identifica o recurso para o qual a solicitação será enviada e usa a RequestProvider classe para invocar o método HTTP GET no recurso, antes de retornar os resultados para o CatalogViewModel. A RequestProvider classe contém funcionalidade que envia uma solicitação na forma de um URI que identifica um recurso, um método HTTP que indica a operação a ser executada nesse recurso e um corpo que contém todos os dados necessários para executar a operação. Para obter informações sobre como a classe é injetada CatalogService RequestProvider na classe, consulte Injeção de dependência.

O exemplo de RequestProvider código a seguir mostra o GetAsync método na classe:

public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);
    HttpResponseMessage response = await httpClient.GetAsync(uri);

    await HandleResponse(response);
    TResult result = await response.Content.ReadFromJsonAsync<TResult>();

    return result;
}

Esse método chama o GetOrCreateHttpClient método, que retorna uma instância da HttpClient classe com os cabeçalhos apropriados definidos. Em seguida, ele envia uma solicitação assíncrona GET para o recurso identificado pelo URI, com a resposta sendo armazenada na HttpResponseMessage instância. O HandleResponse método é então invocado, o que lança uma exceção se a resposta não incluir um código de status HTTP bem-sucedido. Em seguida, a resposta é lida como uma cadeia de caracteres, convertida de JSON para um CatalogRoot objeto e retornada para o CatalogService.

O GetOrCreateHttpClient método é mostrado no exemplo de código a seguir:

private readonly Lazy<HttpClient> _httpClient =
    new Lazy<HttpClient>(
        () =>
        {
            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            return httpClient;
        },
        LazyThreadSafetyMode.ExecutionAndPublication);

private HttpClient GetOrCreateHttpClient(string token = "")
    {
        var httpClient = _httpClient.Value;

        if (!string.IsNullOrEmpty(token))
        {
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
        else
        {
            httpClient.DefaultRequestHeaders.Authorization = null;
        }

        return httpClient;
    }

Esse método usa cria uma nova instância ou recupera uma instância em cache da HttpClient classe e define o cabeçalho Accept de todas as solicitações feitas pela HttpClient instância como , o application/jsonque indica que ele espera que o conteúdo de qualquer resposta seja formatado usando JSON. Em seguida, se um token de acesso foi passado como um argumento para o GetOrCreateHttpClient método, ele é adicionado ao Authorization cabeçalho de todas as solicitações feitas pela instância, prefixadas HttpClient com a cadeia de caracteres Bearer. Para obter mais informações sobre autorização, consulte Autorização.

Gorjeta

É altamente recomendável armazenar em cache e reutilizar instâncias do para um melhor desempenho do HttpClient aplicativo. Criar um novo HttpClient para cada operação pode levar a problemas com a exaustão do soquete. Para obter mais informações, consulte HttpClient Instanciing no Microsoft Developer Center.

Quando o GetAsync método na RequestProvider classe chama HttpClient.GetAsync, o Items método na CatalogController classe no Catalog.API projeto é invocado, que é mostrado no exemplo de código a seguir:

[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);
}

Esse método recupera os dados do catálogo do banco de dados SQL usando EntityFramework e os retorna como uma mensagem de resposta que inclui um código de status HTTP de sucesso e uma coleção de instâncias formatadas JSON CatalogItem .

Fazer um pedido POST

A BasketService classe é usada para gerenciar o processo de recuperação e atualização de dados com o microsserviço da cesta. RegisterAppServices No método na MauiProgram classe, a BasketService classe é registrada como um mapeamento de tipo em relação ao IBasketService tipo com o contêiner de injeção de dependência. Em seguida, quando uma instância da classe é criada, seu construtor aceita um IBasketService tipo, que o contêiner de injeção de BasketViewModel dependência resolve, retornando uma instância da BasketService classe. Para obter mais informações sobre injeção de dependência, consulte Injeção de dependência.

A imagem abaixo mostra a interação das classes que enviam os dados da cesta exibidos pelo BasketView, para o microsserviço da cesta.

Envio de dados para o microsserviço do cesto.

Quando um item é adicionado ao carrinho de compras, o ReCalculateTotalAsync método na BasketViewModel classe é chamado. Esse método atualiza o valor total dos itens na cesta e envia os dados da cesta para o microsserviço da cesta, conforme demonstrado no exemplo de código a seguir:

private async Task ReCalculateTotalAsync()
{
    // Omitted for brevity...

    await _basketService.UpdateBasketAsync(
        new CustomerBasket
        {
            BuyerId = userInfo.UserId, 
            Items = BasketItems.ToList()
        }, 
        authToken);
}

Esse método chama o UpdateBasketAsync BasketService método da instância que foi injetada no BasketViewModel contêiner de injeção de dependência. O método a seguir mostra o UpdateBasketAsync método:

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;
}

Esse método cria o URI que identifica o recurso para o qual a solicitação será enviada e usa a RequestProvider classe para invocar o método HTTP POST no recurso, antes de retornar os resultados para o BasketViewModel. Observe que um token de acesso, obtido durante o processo de autenticação, é necessário para autorizar solicitações ao microsserviço da IdentityServer cesta. Para obter mais informações sobre autorização, consulte Autorização.

O exemplo de código a seguir mostra um dos PostAsync métodos na RequestProvider classe:

public async Task<TResult> PostAsync<TResult>(
    string uri, TResult data, string token = "", string header = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);

    var content = new StringContent(JsonSerializer.Serialize(data));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = await httpClient.PostAsync(uri, content);

    await HandleResponse(response);
    TResult result = await response.Content.ReadFromJsonAsync<TResult>();
    
    return result;
}

Esse método chama o GetOrCreateHttpClient método, que retorna uma instância da HttpClient classe com os cabeçalhos apropriados definidos. Em seguida, ele envia uma solicitação POST assíncrona para o recurso identificado pelo URI, com os dados da cesta serializada sendo enviados no formato JSON e a resposta sendo armazenada na HttpResponseMessage instância. O HandleResponse método é então invocado, o que lança uma exceção se a resposta não incluir um código de status HTTP bem-sucedido. Em seguida, a resposta é lida como uma cadeia de caracteres, convertida de JSON para um CustomerBasket objeto e retornada para o BasketService. Para obter mais informações sobre o GetOrCreateHttpClient método, consulte Fazendo uma solicitação GET.

Quando o PostAsync método na RequestProvider classe chama HttpClient.PostAsync, o Post método na BasketController classe no Basket.API projeto é invocado, que é mostrado no exemplo de código a seguir:

[HttpPost]
public async Task<IActionResult> Post([FromBody] CustomerBasket value)
{
    var basket = await _repository.UpdateBasketAsync(value);
    return Ok(basket);
} 

Esse método usa uma instância da classe para persistir os dados da cesta no cache Redis e os retorna como uma mensagem de resposta que inclui um código de status HTTP bem-sucedido e uma instância formatada RedisBasketRepository JSON CustomerBasket .

Fazer um pedido DELETE

A imagem abaixo mostra as interações das classes que excluem os dados da cesta do microsserviço da cesta, para o CheckoutView.

Exclusão de dados do microsserviço da cesta.

Quando o processo de check-out é invocado, o CheckoutAsync método na CheckoutViewModel classe é chamado. Este método cria uma nova ordem, antes de limpar o carrinho de compras, como demonstrado no exemplo de código a seguir:

private async Task CheckoutAsync()
{
    // Omitted for brevity...

    await _basketService.ClearBasketAsync(
        _shippingAddress.Id.ToString(), authToken);
}

Esse método chama o ClearBasketAsync BasketService método da instância que foi injetada no CheckoutViewModel contêiner de injeção de dependência. O método a seguir mostra o ClearBasketAsync método:

public async Task ClearBasketAsync(string guidUser, string token)
{
    UriBuilder builder = new(GlobalSetting.Instance.BasketEndpoint);
    builder.Path = guidUser;
    string uri = builder.ToString();
    await _requestProvider.DeleteAsync(uri, token);
}

Esse método cria o URI que identifica o recurso para o qual a solicitação será enviada e usa a RequestProvider classe para invocar o DELETE método HTTP no recurso. Observe que um token de acesso, obtido durante o processo de autenticação, é necessário para autorizar solicitações ao microsserviço da IdentityServer cesta. Para obter mais informações sobre autorização, consulte Autorização.

O exemplo de RequestProvider código a seguir mostra o DeleteAsync método na classe:

public async Task DeleteAsync(string uri, string token = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);
    await httpClient.DeleteAsync(uri);
}

Esse método chama o GetOrCreateHttpClient método, que retorna uma instância da HttpClient classe com os cabeçalhos apropriados definidos. Em seguida, ele envia uma solicitação assíncrona DELETE para o recurso identificado pelo URI. Para obter mais informações sobre o GetOrCreateHttpClient método, consulte Fazendo uma solicitação GET.

Quando o DeleteAsync método na RequestProvider classe chama HttpClient.DeleteAsync, o Delete método na BasketController classe no Basket.API projeto é invocado, que é mostrado no exemplo de código a seguir:

[HttpDelete("{id}")]
public void Delete(string id) =>
    _repository.DeleteBasketAsync(id);

Esse método usa uma instância da RedisBasketRepository classe para excluir os dados da cesta do cache Redis.

Colocar dados em cache

O desempenho de um aplicativo pode ser melhorado armazenando em cache dados acessados com frequência em um armazenamento rápido localizado próximo ao aplicativo. Se o armazenamento rápido estiver localizado mais perto do aplicativo do que a fonte original, o cache pode melhorar significativamente os tempos de resposta ao recuperar dados.

A forma mais comum de cache é o cache de leitura, em que um aplicativo recupera dados fazendo referência ao cache. Se os dados não estiverem na cache, são obtidos a partir do arquivo de dados e adicionados à cache. Os aplicativos podem implementar o cache de leitura com o padrão cache-side. Esse padrão determina se o item está atualmente no cache. Se o item não estiver no cache, ele será lido do armazenamento de dados e adicionado ao cache. Para obter mais informações, consulte o padrão Cache-Aside no Microsoft Docs.

Gorjeta

Armazene em cache dados lidos com frequência e alterados com pouca frequência.

Esses dados podem ser adicionados ao cache sob demanda na primeira vez que são recuperados por um aplicativo. Isso significa que o aplicativo precisa buscar os dados apenas uma vez no armazenamento de dados e que o acesso subsequente pode ser satisfeito usando o cache.

Os aplicativos distribuídos, como o aplicativo de referência eShop, devem fornecer um ou ambos os seguintes caches:

  • Um cache compartilhado, que pode ser acessado por vários processos ou máquinas.
  • Um cache privado, onde os dados são mantidos localmente no dispositivo que executa o aplicativo.

O aplicativo multiplataforma eShop usa um cache privado, onde os dados são mantidos localmente no dispositivo que está executando uma instância do aplicativo.

Gorjeta

Pense no cache como um armazenamento de dados transitório que pode desaparecer a qualquer momento.

Certifique-se de que os dados são mantidos no armazenamento de dados original, bem como no cache. As chances de perda de dados são minimizadas se o cache ficar indisponível.

Gerenciando a expiração de dados

É impraticável esperar que os dados armazenados em cache sejam sempre consistentes com os dados originais. Os dados no armazenamento de dados original podem ser alterados depois de serem armazenados em cache, fazendo com que os dados armazenados em cache se tornem obsoletos. Portanto, os aplicativos devem implementar uma estratégia que ajude a garantir que os dados no cache estejam o mais atualizados possível, mas também possam detetar e lidar com situações que surgem quando os dados no cache se tornaram obsoletos. A maioria dos mecanismos de cache permite que o cache seja configurado para expirar dados e, portanto, reduzir o período durante o qual os dados podem estar desatualizados.

Gorjeta

Defina um tempo de expiração padrão ao configurar um cache.

Muitos caches implementam a expiração, que invalida os dados e os remove do cache se não forem acessados por um período especificado. No entanto, é preciso ter cuidado ao escolher o período de validade. Se for muito curto, os dados expirarão muito rapidamente e os benefícios do cache serão reduzidos. Se for feito por muito tempo, os dados correm o risco de se tornarem obsoletos. Portanto, o tempo de expiração deve corresponder ao padrão de acesso para aplicativos que usam os dados.

Quando os dados armazenados em cache expirarem, eles devem ser removidos do cache e o aplicativo deve recuperar os dados do armazenamento de dados original e colocá-los de volta no cache.

Também é possível que um cache fique cheio se os dados puderem permanecer por um período muito longo. Portanto, solicitações para adicionar novos itens ao cache podem ser necessárias para remover alguns itens em um processo conhecido como remoção. Os serviços de cache normalmente removem dados em uma base menos usada recentemente. No entanto, existem outras políticas de despejo, incluindo as mais recentes e as mais recentes. Para obter mais informações, consulte Diretrizes de cache no Microsoft Docs.

Armazenamento em cache de imagens

A aplicação multiplataforma eShop consome imagens de produtos remotos que beneficiam de serem armazenadas em cache. Essas imagens são exibidas pelo controle Image. O controle de imagem .NET MAUI suporta o cache de imagens baixadas que tem o cache habilitado por padrão e armazenará a imagem localmente por 24 horas. Além disso, o tempo de expiração pode ser configurado com a propriedade CacheValidity. Para obter mais informações, consulte Cache de imagens baixado no Microsoft Developer Center.

Aumentar a resiliência

Todos os aplicativos que se comunicam com serviços e recursos remotos devem ser sensíveis a falhas transitórias. As falhas transitórias incluem a perda momentânea de conectividade de rede para serviços, a indisponibilidade temporária de um serviço ou tempos limite que surgem quando um serviço está ocupado. Essas falhas geralmente são autocorretivas e, se a ação for repetida após um atraso adequado, é provável que tenha sucesso.

Falhas transitórias podem ter um enorme impacto na qualidade percebida de um aplicativo, mesmo que ele tenha sido exaustivamente testado em todas as circunstâncias previsíveis. Para garantir que um aplicativo que se comunica com serviços remotos opere de forma confiável, ele deve ser capaz de fazer o seguinte:

  • Detete falhas quando elas ocorrerem e determine se elas provavelmente serão transitórias.
  • Repita a operação se determinar que a falha provavelmente será transitória e acompanhe o número de vezes que a operação foi repetida.
  • Use uma estratégia de repetição apropriada, que especifica o número de tentativas, o atraso entre cada tentativa e as ações a serem tomadas após uma tentativa falhada.

Esse tratamento de falhas transitórias pode ser alcançado encapsulando todas as tentativas de acessar um serviço remoto no código que implementa o padrão de repetição.

Padrão de Repetição

Se um aplicativo detetar uma falha ao tentar enviar uma solicitação para um serviço remoto, ele poderá lidar com a falha de qualquer uma das seguintes maneiras:

  • Repetindo a operação. O aplicativo pode repetir a solicitação com falha imediatamente.
  • Repetir a operação após um atraso. O aplicativo deve aguardar por um período de tempo adequado antes de tentar novamente a solicitação.
  • Cancelamento da operação. O aplicativo deve cancelar a operação e relatar uma exceção.

A estratégia de repetição deve ser ajustada para corresponder aos requisitos de negócios do aplicativo. Por exemplo, é importante otimizar a contagem de repetições e o intervalo de repetição para a operação que está sendo tentada. Se a operação fizer parte de uma interação do usuário, o intervalo de repetição deve ser curto e apenas algumas tentativas devem ser tentadas para evitar que os usuários esperem por uma resposta. Se a operação fizer parte de um fluxo de trabalho de longa execução, em que cancelar ou reiniciar o fluxo de trabalho é caro ou demorado, é apropriado esperar mais tempo entre as tentativas e tentar novamente mais vezes.

Nota

Uma estratégia agressiva de repetição com atraso mínimo entre as tentativas e um grande número de tentativas pode degradar um serviço remoto que está sendo executado perto ou na capacidade. Além disso, essa estratégia de repetição também pode afetar a capacidade de resposta do aplicativo se ele estiver continuamente tentando executar uma operação com falha.

Se uma solicitação ainda falhar após várias tentativas, é melhor para o aplicativo impedir que novas solicitações vão para o mesmo recurso e relatar uma falha. Em seguida, após um período definido, o aplicativo pode fazer uma ou mais solicitações ao recurso para ver se elas são bem-sucedidas. Para obter mais informações, consulte Padrão do disjuntor.

Gorjeta

Nunca implemente um mecanismo de repetição permanente. Em vez disso, prefira um recuo exponencial.

Use um número finito de tentativas ou implemente o padrão Disjuntor para permitir a recuperação de um serviço.

O aplicativo de referência eShop implementa o padrão de repetição.

Para obter mais informações sobre o padrão de repetição, consulte o padrão de repetição no Microsoft Docs.

Padrão do disjuntor

Em algumas situações, as falhas podem ocorrer devido a eventos antecipados que levam mais tempo para serem corrigidos. Essas falhas podem variar de uma perda parcial de conectividade até a falha completa de um serviço. Nessas situações, é inútil para um aplicativo tentar novamente uma operação que provavelmente não terá êxito e, em vez disso, deve aceitar que a operação falhou e lidar com essa falha de acordo.

O padrão de disjuntor pode impedir que um aplicativo tente executar repetidamente uma operação que provavelmente falhará, ao mesmo tempo em que permite que o aplicativo detete se a falha foi resolvida.

Nota

A finalidade do padrão do disjuntor é diferente do padrão de repetição. O padrão de repetição permite que um aplicativo tente novamente uma operação na expectativa de que ela seja bem-sucedida. O padrão do disjuntor impede que um aplicativo execute uma operação que provavelmente falhará.

Um disjuntor automático atua como proxy para operações suscetíveis de falhar. O proxy deve monitorar o número de falhas recentes que ocorreram e usar essas informações para decidir se permite que a operação prossiga ou se retorna uma exceção imediatamente.

Atualmente, o aplicativo multiplataforma eShop não implementa o padrão de disjuntor. No entanto, a eShop sim.

Gorjeta

Combine os padrões de repetição e disjuntor.

Um aplicativo pode combinar os padrões de repetição e disjuntor usando o padrão de repetição para invocar uma operação por meio de um disjuntor. No entanto, a lógica de repetição deve ser sensível a eventuais exceções devolvidas pelo disjuntor automático e abandonar tentativas de repetição se o disjuntor automático indicar que uma falha não é transitória.

Para obter mais informações sobre o padrão do disjuntor, consulte o padrão do disjuntor no Microsoft Docs.

Resumo

Muitas soluções modernas baseadas na Web fazem uso de serviços da Web, hospedados por servidores da Web, para fornecer funcionalidade para aplicativos cliente remotos. As operações que um serviço Web expõe constituem uma API da Web, e os aplicativos cliente devem ser capazes de utilizar a API da Web sem saber como os dados ou operações que a API expõe são implementados.

O desempenho de um aplicativo pode ser melhorado armazenando em cache dados acessados com frequência em um armazenamento rápido localizado próximo ao aplicativo. Os aplicativos podem implementar o cache de leitura com o padrão cache-side. Esse padrão determina se o item está atualmente no cache. Se o item não estiver no cache, ele será lido do armazenamento de dados e adicionado ao cache.

Ao se comunicar com APIs da Web, os aplicativos devem ser sensíveis a falhas transitórias. As falhas transitórias incluem a perda momentânea de conectividade de rede para serviços, a indisponibilidade temporária de um serviço ou tempos limite que surgem quando um serviço está ocupado. Essas falhas geralmente são autocorretivas e, se a ação for repetida após um atraso adequado, é provável que tenha sucesso. Portanto, os aplicativos devem encapsular todas as tentativas de acessar uma API da Web em código que implemente um mecanismo transitório de tratamento de falhas.