Livro Texto - Unidade IV

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 46

DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Unidade IV
7 INTRODUÇÃO AO DESENVOLVIMENTO MÓVEL COM REACT NATIVE

O desenvolvimento de aplicações móveis tem sido uma área de crescimento contínuo na indústria de
tecnologia, com uma demanda crescente por soluções que sejam não apenas funcionais, mas também
escaláveis e eficientes. Nesse cenário, uma tecnologia se destaca por sua relevância e capacidade de
atender a essa demanda: React Native, uma criação do Facebook que aborda o desenvolvimento móvel
de uma maneira diferente.

O React Native permite aos desenvolvedores construir aplicações móveis usando JavaScript e
React, uma biblioteca JavaScript para construir interfaces de usuário. O que diferencia essa tecnologia
de outras abordagens de desenvolvimento móvel é sua capacidade de compilar aplicações para
plataformas nativas, como iOS e Android, a partir de uma base de código comum. Isso significa que
os desenvolvedores podem aproveitar suas habilidades existentes em JavaScript para criar aplicativos
móveis que ofereçam uma experiência de usuário quase indistinguível daquelas construídas com
Swift ou Kotlin, as linguagens nativas para iOS e Android, respectivamente. Além disso, React Native
oferece uma experiência de desenvolvimento ágil, com recursos como o hot reloading, que permite aos
desenvolvedores visualizarem as alterações quase instantaneamente sem a necessidade de recompilar
a aplicação inteira.

A integração entre ASP.NET Core e React Native pode ser particularmente eficiente para o
desenvolvimento de soluções móveis. Enquanto o ASP.NET Core pode servir como uma robusta back‑end,
gerenciando lógica de negócios, banco de dados e autenticação, o React Native pode ser utilizado para
construir o front‑end, criando interfaces de usuário atraentes e responsivas. Essa combinação permite
que as equipes de desenvolvimento criem aplicações móveis completas, com um back‑end sólido e uma
experiência de usuário imersiva.

Portanto, o desenvolvimento de aplicações móveis contemporâneas exige uma abordagem que


atenda às expectativas dos usuários finais em termos de funcionalidade e experiência de usuário e
que também ofereça aos desenvolvedores as ferramentas necessárias para construir essas soluções
de maneira eficiente e sustentável. Nesse contexto, tecnologias como ASP.NET Core e React Native
desempenham papéis fundamentais, permitindo a criação de aplicações poderosas e adaptáveis, que
podem evoluir com as necessidades do mercado.

209
Unidade IV

7.1 Introdução ao React Native

Este framework, introduzido pelo Facebook em 2015, foi projetado para permitir o desenvolvimento
de aplicações móveis nativas utilizando JavaScript e React, uma biblioteca popular para construir
interfaces de usuário web. A inovação trazida pelo React Native reside na sua capacidade de usar o mesmo
código‑base para criar aplicativos tanto para iOS quanto para Android, duas das principais plataformas
móveis do mercado, otimizando assim o processo de desenvolvimento e reduzindo significativamente o
tempo e o custo associados.

O React Native se baseia no conceito de “aprender uma vez, escrever em qualquer lugar”, permitindo
que desenvolvedores com experiência em JavaScript construam aplicações que se comportam como
nativas e também têm a aparência e a sensibilidade de aplicações nativas. Isso é alcançado pelo uso de
componentes nativos do sistema operacional, que são manipulados pelo código JavaScript, permitindo
que o React Native ofereça uma experiência de usuário final indistinguível de uma aplicação construída
utilizando as linguagens nativas específicas de cada plataforma, como Swift para iOS ou Kotlin
para Android.

Um dos aspectos mais atraentes do React Native, além da sua capacidade cross-platform, é a
eficiência no processo de desenvolvimento que ele promove. Lembre-se que o framework suporta
o hot reloading, que permite aos desenvolvedores ver imediatamente as mudanças feitas no código
em seus aplicativos, sem a necessidade de recompilar todo o projeto. Essa característica acelera o
desenvolvimento e facilita a experimentação e a iteração rápida, elementos essenciais na criação de
uma boa experiência do usuário.

No entanto, o React Native não está isento de desafios. A ponte entre o código JavaScript e
os componentes nativos, embora eficiente, pode ocasionalmente ser uma fonte de gargalos de
desempenho. Além disso, aplicações que requerem uma grande quantidade de interações da plataforma
ou que necessitam de uma integração profunda com recursos do sistema operacional ainda podem
exigir que os desenvolvedores escrevam algum código nativo, potencialmente complicando o processo
de desenvolvimento.

Apesar desses desafios, a contribuição do React Native para o desenvolvimento móvel é inegável. Ele
democratizou o acesso ao desenvolvimento de aplicações móveis nativas para muitos desenvolvedores,
permitindo àqueles com conhecimento em JavaScript entrar no mercado móvel sem a necessidade
de aprender novas linguagens de programação. Além disso, o ecossistema em torno do React Native
tem crescido exponencialmente, com uma vasta biblioteca de componentes de terceiros disponíveis,
permitindo uma personalização e funcionalidade ainda maiores nas aplicações desenvolvidas.

7.2 Componentes fundamentais do React Native

Um dos pilares do React Native é o uso de componentes, que são blocos de construção
encapsulados que gerenciam seu próprio estado. Esses componentes permitem aos desenvolvedores
construir interfaces complexas através da composição de elementos simples, promovendo reutilização
de código e separação de preocupações. Os componentes no React Native são divididos em dois tipos
210
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

principais: componentes de interface de usuário nativos e componentes personalizados. Os primeiros


correspondem aos elementos de interface do usuário nativos do sistema operacional, como botões, vistas
e barras de rolagem, que garantem que a aplicação mantenha a aparência e a sensação da plataforma
para a qual está sendo desenvolvida. Já os personalizados são definidos pelos próprios desenvolvedores
e podem encapsular uma complexidade significativa, oferecendo uma flexibilidade imensa no design da
interface de usuário.

Outro componente fundamental do React Native é o Virtual DOM, uma abstração leve do Document
Object Model (DOM) usado na web. No contexto do React Native, o Virtual DOM permite a atualização
eficiente das interfaces de usuário ao minimizar as manipulações necessárias nos componentes nativos
da plataforma. Quando o estado de um componente muda, o React Native recalcula a representação
virtual da interface de usuário e determina o conjunto mínimo de alterações necessárias para atualizar
a interface de usuário nativa. Esse processo, conhecido como reconciliação, otimiza o desempenho ao
reduzir a quantidade de comunicação necessária entre o JavaScript e a camada nativa.

O mecanismo de ponte é outro componente importante do React Native, que facilita a comunicação
entre o código JavaScript e os componentes nativos da plataforma. Essa ponte é responsável por enviar
mensagens de forma assíncrona entre o ambiente de execução do JavaScript e o código nativo, permitindo
que funcionalidades específicas da plataforma sejam acessadas e manipuladas pelo JavaScript. Esse
sistema de comunicação assíncrono é fundamental para manter a fluidez e a responsividade das
aplicações React Native, mesmo durante operações pesadas ou de longa duração.

Além disso, o React Native proporciona um sistema de layout flexível inspirado no Flexbox, que
é utilizado no desenvolvimento web. Esse sistema permite que desenvolvedores criem interfaces de
usuário adaptáveis a diferentes tamanhos de tela e orientações de dispositivo, usando um modelo de
layout intuitivo. Com o Flexbox, é possível alinhar e distribuir espaços entre os componentes de interface
de usuário em uma aplicação, garantindo que ela tenha uma aparência ótima em diferentes dispositivos.

Finalmente, a comunidade e o ecossistema que cercam o React Native são componentes intangíveis,
mas igualmente fundamentais para seu sucesso. Uma vasta biblioteca de componentes de terceiros,
plugins e extensões estão disponíveis, permitindo que os desenvolvedores incorporem funcionalidades
avançadas e se concentrem na criação de experiências de usuário únicas, sem reinventar a roda.

7.3 Integrando React Native com ASP.NET WebAPI

A integração do React Native com ASP.NET Core WebAPI é uma estratégia avançada que abraça
as especificidades do desenvolvimento de aplicações móveis e web, focando os detalhes operacionais
e as exigências de ambiente que tal integração demanda. Essa abordagem realça a flexibilidade e a
eficácia do React Native no desenvolvimento de interfaces de usuário para dispositivos móveis e,
ao mesmo tempo, capitaliza a robustez e a escalabilidade do ASP.NET Core para gerenciar lógicas de
negócio complexas e operações de back‑end.

211
Unidade IV

Uma das primeiras considerações ao se usar React Native é o ambiente de desenvolvimento,


particularmente para desenvolvedores que visam plataformas iOS e Android. Para o Android, a instalação
do Android Studio é indispensável. Ele não só fornece um ambiente de desenvolvimento rico, mas
também é essencial para gerenciar emuladores Android, configurar dispositivos virtuais para testes e
gerenciar versões do Android SDK. O Android Studio é um hub central para testar e depurar aplicações
React Native no Android, apesar do código JavaScript ser editável em qualquer editor de texto ou IDE
de preferência do desenvolvedor.

No caso do desenvolvimento iOS com React Native, a necessidade de um Mac é incontornável.


O Xcode, exclusivo para macOS, é o ambiente de desenvolvimento oficial para aplicativos iOS, sendo
necessário não apenas para compilar aplicações para a plataforma iOS, mas também para configurar
emuladores iOS, gerenciar certificados de desenvolvedor e acessar muitas outras ferramentas específicas
do iOS. Essa exigência pode representar uma barreira para desenvolvedores ou equipes que não têm
acesso a hardware Apple, mas é uma realidade imposta por seu ecossistema fechado.

Na integração de React Native com o ASP.NET Core WebAPI, a comunicação entre o front‑end
móvel e o back‑end ocorre através de chamadas de API RESTful. O ASP.NET Core facilita a criação desses
endpoints de API, que podem ser consumidos pelo aplicativo React Native para realizar operações
como autenticação de usuário, recuperação de dados e outras transações específicas do negócio. Essa
comunicação é tipicamente realizada por solicitações HTTP, com dados enviados e recebidos no formato
JSON, um padrão bem suportado tanto pelo ASP.NET Core quanto pelo React Native.

A autenticação é um ponto crítico dessa integração, especialmente considerando os diferentes


ambientes de execução. O ASP.NET Core oferece suporte para autenticação baseada em token, como o
JWT (JSON Web Tokens), que pode ser implementado para manter as comunicações entre o aplicativo
React Native e o servidor. Esse método de autenticação é compatível com ambas as plataformas, iOS
e Android, garantindo que os dados do usuário sejam transmitidos de forma segura. Cabe destacar
que a integração eficaz entre React Native e ASP.NET Core WebAPI requer uma atenção meticulosa
ao tratamento de erros e validação de dados, para prevenir a entrada de dados mal-intencionados ou
corrompidos. Isso implica a implementação de validações tanto no cliente (React Native) quanto no
servidor (ASP.NET Core), além de um tratamento de erro que informe os usuários, de maneira intuitiva,
o que deu errado.

7.4 Autenticação e segurança em aplicativos móveis

No desenvolvimento de aplicativos móveis a autenticação e a segurança são áreas críticas, que


demandam atenção meticulosa para proteger tanto os dados do usuário quanto os sistemas contra
acessos não autorizados e vulnerabilidades diversas. À medida que o cenário tecnológico evolui,
também evoluem as técnicas e estratégias para assegurar aplicativos móveis, especialmente aqueles
desenvolvidos com tecnologias modernas como ASP.NET Core para o back-end, que oferece várias
funcionalidades de segurança e autenticação prontas para uso, facilitando a implementação de práticas
de segurança robustas sem comprometer a eficiência do desenvolvimento.

212
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

A autenticação é o processo pelo qual uma aplicação verifica a identidade de um usuário, geralmente
com nome de usuário e senha, tokens de autenticação ou outros métodos, como biometria. Em ambientes
móveis, a autenticação não apenas restringe o acesso a recursos sensíveis, mas também personaliza a
experiência do usuário ao garantir que ele tenha acesso apenas aos dados e funcionalidades relevantes
para seu perfil. ASP.NET Core suporta diversos mecanismos de autenticação, incluindo autenticação
baseada em token, como JWT (JSON Web Tokens), que é particularmente adequada para aplicativos
móveis devido a sua natureza sem estado, permitindo que o servidor valide o token do cliente sem a
necessidade de manter um estado de sessão.

Além da autenticação, a segurança de um aplicativo móvel abrange a proteção dos dados


transmitidos entre o cliente e o servidor, a segurança do próprio servidor e a proteção dos
dados armazenados no dispositivo do usuário. ASP.NET Core contribui para a segurança dos dados
em trânsito através do suporte nativo a HTTPS, garantindo que todos os dados transmitidos sejam
criptografados, protegendo‑os contra interceptação ou manipulação por terceiros. Para a segurança
do servidor, o framework oferece funcionalidades como o CORS (Cross‑Origin Resource Sharing),
que permite que os desenvolvedores controlem quais domínios podem acessar os recursos da
API, e proteções contra vulnerabilidades comuns como SQL Injection, Cross‑site scripting (XSS)
e Cross‑site request forgery (CSRF). Quanto à segurança dos dados no dispositivo, embora o
ASP.NET Core atue principalmente no lado do servidor, as práticas recomendadas incluem a utilização
de armazenamento seguro para credenciais, chaves de autenticação e dados sensíveis, além da
implementação de medidas como criptografia de dados em repouso e ofuscação de código para
proteger a lógica de negócios e os dados do aplicativo contra engenharia reversa.

Observação

A ofuscação de código é uma técnica de proteção do código-fonte de


uma aplicação, tornando-o de difícil leitura para humanos ou máquinas,
especialmente aquelas com intenções maliciosas. Isso é particularmente
útil em ambientes .NET devido à natureza do código compilado, que pode
ser facilmente descompilado para formas quase originais com ferramentas
disponíveis publicamente.

A ofuscação transforma o código compilado (como nomes de variáveis,


métodos e classes) em algo que retém a mesma funcionalidade, mas se
torna extremamente desafiador de ser interpretado. Por exemplo, uma
variável chamada “numeroDeUsuariosOnline” pode ser renomeada como
“a1”, e métodos podem ter seus nomes alterados de maneira semelhante.
Além disso, a ofuscação pode envolver a alteração da estrutura do código,
como modificar a ordem das operações ou inserir um código que não afeta a
funcionalidade, mas confunde ainda mais qualquer pessoa ou software que
tente analisá-lo. Isso é particularmente valioso para proteger a propriedade
intelectual e aumentar a segurança, pois dificulta a engenharia reversa, a
análise de vulnerabilidades ou a modificação maliciosa do código.
213
Unidade IV

A implementação dessa técnica pode ser feita de várias formas, desde


soluções simples e gratuitas até ferramentas comerciais avançadas que
oferecem recursos adicionais, como criptografia de strings, ocultação
de chamadas de métodos e proteção contra a descompilação. Algumas
ferramentas de ofuscação que podem ser usadas com o Visual Studio são
Dotfuscator, Obfuscar, e Eazfuscator.NET. Cada uma delas tem seu próprio
conjunto de funcionalidades e métodos de integração com o Visual Studio,
permitindo que os desenvolvedores escolham a solução que melhor se
adapta às suas necessidades.

Apesar de ser uma camada importante de segurança, a ofuscação


deve ser vista como parte de uma estratégia de segurança em múltiplas
camadas, complementando outras práticas, como a minificação de código,
uso de HTTPS, e atualizações regulares de segurança, porque a ofuscação
complica a tarefa de entender o código, mas não o torna inquebrável.

A autenticação e a segurança em aplicativos móveis desenvolvidos com ASP.NET Core, portanto, não
se limitam ao controle de acesso. Elas abrangem uma série de práticas e técnicas destinadas a proteger
todos os aspectos do aplicativo e da interação do usuário. Desde o processo de autenticação até a
proteção dos dados em trânsito e no dispositivo do usuário, uma abordagem holística e em camadas
para a segurança é essencial para construir aplicações móveis não apenas funcionais, mas também
confiáveis e seguras. Essa abordagem integral assegura que a privacidade e a integridade dos dados do
usuário sejam mantidas, fortalecendo a confiança no aplicativo e, por extensão, a marca por trás dele.

7.5 Deploy de um aplicativo React Native

O desenvolvimento de aplicativos modernos frequentemente envolve a combinação de tecnologias


e frameworks para atender as necessidades de negócios e experiência do usuário. Um exemplo
disso é o uso de ASP.NET Core para construir o back‑end de um aplicativo com React Native para o
desenvolvimento da interface de usuário móvel. Essa combinação oferece a robustez e eficiência do
ASP.NET Core com a flexibilidade e o alcance multiplataforma do React Native. No entanto, um dos
desafios mais significativos dessa abordagem é o deploy eficaz do aplicativo React Native, assegurando
que o front‑end e o back‑end se comuniquem corretamente e performem de maneira eficiente em
ambientes de produção.

O processo de deploy de um aplicativo React Native, com um back-end ASP.NET Core, envolve várias
etapas críticas. Primeiramente, é essencial garantir que o ambiente de produção esteja corretamente
configurado para suportar as tecnologias envolvidas. Isso pode incluir a configuração de servidores,
definição de políticas de segurança e a instalação de dependências necessárias para o ASP.NET Core e o
ambiente de execução do React Native.

Após a preparação do ambiente, a próxima etapa envolve a construção (build) e o empacotamento


do aplicativo React Native. Esta etapa transforma o código-fonte, que inclui JavaScript, CSS e outros
recursos em um pacote que pode ser distribuído e executado em dispositivos móveis. O React Native
214
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

oferece ferramentas que facilitam esse processo, permitindo a geração de aplicativos nativos para
Android e iOS a partir de uma base de código unificada.

O quadro 34 apresenta algumas dessas ferramentas e recursos que fornecem aos desenvolvedores
uma poderosa suite para a criação de aplicativos React Native eficientes e de alta qualidade, aproveitando
a reutilização de código entre plataformas e a ampla comunidade de suporte para resolver desafios
comuns de desenvolvimento.

Concomitantemente, o back‑end ASP.NET Core deve ser preparado para deploy, o que inclui a
compilação do código C#, configurações de ambiente e a possível integração com bancos de dados e
serviços externos. O ASP.NET Core suporta várias estratégias de deploy, incluindo contêineres Docker
(como vimos no tópico 5), o que pode simplificar a implantação e a gestão de ambientes de produção,
especialmente em arquiteturas de microsserviços. Uma vez que o front-end e o back-end estejam prontos,
é preciso estabelecer uma comunicação efetiva entre eles. Isso geralmente envolve a configuração
de endpoints de API no back-end ASP.NET Core e a utilização desses endpoints no aplicativo React
Native para realizar chamadas de rede, autenticação de usuários e outras interações dinâmicas.

O monitoramento e a manutenção contínua são também aspectos críticos após o deploy. Ferramentas
e práticas de DevOps, incluindo integração contínua e entrega contínua, podem ser empregadas para
automatizar testes, builds e deploys, garantindo que o aplicativo permaneça estável, seguro e atualizado.

Quadro 34 – Ferramentas úteis no deploy para React Native

Uma das ferramentas mais populares na comunidade React Native, o Expo é uma
plataforma de código aberto que oferece um conjunto de ferramentas e serviços
projetados para facilitar o desenvolvimento de aplicativos React Native. Com o
Expo Expo, os desenvolvedores podem criar, testar e implantar rapidamente aplicativos
sem a necessidade de configurar ambientes de desenvolvimento nativos. Ele fornece
acesso a APIs nativas do dispositivo sem a necessidade de escrever código nativo,
além de suportar atualizações ao vivo do aplicativo

O Metro é o empacotador (bundler) padrão para React Native, responsável por


empacotar o código JavaScript e todos os seus recursos em um único arquivo que
Metro Bundler pode ser executado na plataforma-alvo. Ele otimiza o código para melhorar o
desempenho e a eficiência, permitindo que os aplicativos carreguem rapidamente
nos dispositivos dos usuários

A interface de linha de comando (CLI) do React Native é uma ferramenta essencial


para o desenvolvimento de aplicativos. Ela permite aos desenvolvedores criar
novos projetos, executar o aplicativo em emuladores ou dispositivos físicos e
React Native CLI acessar diversas funcionalidades de desenvolvimento diretamente do terminal. Essa
ferramenta é particularmente útil para aqueles que preferem uma abordagem mais
manual e têm a necessidade de configurações personalizadas

O React Native oferece recursos como Hot Reloading e Live Reloading, que
aumentam significativamente a produtividade do desenvolvimento ao permitir que
Hot Reloading e Live Reloading as alterações no código sejam visualizadas em tempo real, sem a necessidade de
recompilar todo o aplicativo. Isso ajuda os desenvolvedores a iterar rapidamente
durante o desenvolvimento

215
Unidade IV

É uma plataforma de depuração para aplicativos móveis que suporta React Native.
O Flipper oferece uma variedade de plugins que permitem aos desenvolvedores
inspecionar, monitorar e depurar seus aplicativos de maneira eficiente. Desde
Flipper visualizar logs até inspecionar a árvore de componentes React e monitorar as
chamadas de rede, o Flipper é uma ferramenta abrangente para garantir a qualidade
e a performance dos aplicativos
Esta é uma extensão do navegador Chrome que permite aos desenvolvedores
inspecionar a hierarquia de componentes React em seus aplicativos com o estado
React Developer Tools e as props atuais. Quando usada com React Native, ajuda a entender como os
componentes estão renderizando e interagindo entre si, facilitando a depuração e a
otimização do desempenho

Saiba mais

Uma leitura interessante para aprofundamento em React Native é o


livro React Native in action, que oferece uma introdução abrangente ao
desenvolvimento de aplicativos móveis com React Native, cobrindo desde
os fundamentos até tópicos avançados. Ele inclui a criação de componentes
personalizados, navegação e gestão de estado.

DABIT, N. React native in action. Shelter Island: Manning, 2019.

7.6 Otimização e performance

A otimização e a performance são aspectos que influenciam diretamente a experiência do usuário


e a eficiência operacional e o ASP.NET Core oferece uma variedade de recursos e estratégias para
otimizar o desempenho da aplicação. Ressalta-se a necessidade crescente de que aplicações atendam
às expectativas funcionais dos usuários e respondam a interações rapidamente, independentemente da
carga de trabalho ou do volume de tráfego.

A otimização no contexto do ASP.NET Core abrange várias áreas, desde o design da aplicação e
arquitetura de software até a implementação específica de recursos e a configuração do ambiente
de execução. Um dos primeiros passos para alcançar uma alta performance é a adoção de práticas de
design de software eficientes, como a aplicação dos princípios SOLID para a criação de módulos
coesos e desacoplados, facilitando a manutenção e a escalabilidade. Além disso, a escolha de padrões
arquiteturais adequados, como o modelo de arquitetura em camadas ou microsserviços, pode impactar
significativamente a capacidade de resposta e a eficiência da aplicação.

O ASP.NET Core suporta nativamente a assincronicidade, permitindo que as aplicações web


manipulem múltiplas requisições simultaneamente sem bloquear recursos, o que é fundamental
para a construção de aplicações escaláveis e responsivas. A utilização de operações assíncronas para
acessar bancos de dados, serviços de rede e arquivos pode reduzir o tempo de resposta e aumentar a
taxa de transferência da aplicação. Outrossim, a otimização do desempenho passa pela eficiente gestão
de recursos, como a utilização de cache para armazenar dados frequentemente acessados, reduzindo
assim a necessidade de operações dispendiosas de I/O ou consultas a bancos de dados.
216
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Como vimos anteriormente, o ASP.NET Core oferece várias opções de cache – incluindo cache
em memória e distribuído – que podem ser configuradas para atender às necessidades da aplicação.
A minificação de arquivos CSS e JavaScript, com a compressão de respostas HTTP, são técnicas adicionais
que reduzem o tamanho dos dados transmitidos entre o servidor e o cliente, melhorando os tempos de
carregamento de páginas e a eficiência de banda. O ASP.NET Core facilita essas otimizações por meio
de middleware integrado e ferramentas de build, permitindo uma implementação relativamente simples.

Outro aspecto importante da otimização de performance no ASP.NET Core é a atenção à segurança


e à eficiência das consultas a banco de dados. O uso de ORM (Object-Relational Mapping) como o Entity
Framework Core pode aumentar a produtividade do desenvolvimento, mas requer cuidado para evitar
problemas comuns de performance, como o n+1 query problem. Profiling e otimização de consultas,
com a seleção cuidadosa de índices e estratégias de armazenamento de dados, são essenciais para
manter uma alta performance de acesso a dados.

Observação

O problema n+1 queries é um desafio comum em desenvolvimento de


software que ocorre quando um sistema executa uma consulta inicial ao
banco de dados e, para cada registro retornado por essa consulta, realiza
uma nova. Esse padrão de acesso ao banco de dados é particularmente
ineficiente e pode levar a uma degradação significativa do desempenho
em aplicações que dependem de acesso a bancos de dados relacionais.
Imagine, por exemplo, um cenário em que você tem uma aplicação que
precisa exibir uma lista de usuários e, para cada usuário, todas as suas
postagens em um blog. Uma abordagem ingênua para implementar essa
funcionalidade seria primeiro executar uma consulta para buscar todos
os usuários. Em seguida, para cada usuário retornado, uma nova consulta
seria disparada para buscar suas respectivas postagens. Se tivermos
n usuários, isso resultaria em 1 consulta para buscar todos os usuários,
mais n consultas adicionais para buscar as postagens de cada usuário,
totalizando n+1 consultas ao banco de dados.

O principal impacto do problema n+1 queries é o aumento substancial


do tempo de resposta da aplicação, especialmente à medida que o volume
de dados cresce. Cada consulta ao banco de dados envolve latência de rede,
processamento do banco de dados e, frequentemente, bloqueios em nível
de transação, que, quando acumulados, podem levar a uma experiência de
usuário pobre devido a tempos de carregamento prolongados. Para resolver
ou mitigar o problema n+1 queries, várias estratégias podem ser adotadas:
eager loading (carregamento antecipado), batch loading (carregamento em
lote) e caching.

217
Unidade IV

Em resumo, a otimização de aplicações desenvolvidas com ASP.NET Core é um processo multifacetado,


que envolve desde decisões arquiteturais e de design até técnicas específicas de codificação e
configuração. A adoção dessas práticas e estratégias melhora a performance e a escalabilidade das
aplicações e contribui para uma experiência de usuário mais ágil e satisfatória. Ao investir no desempenho
da aplicação, as organizações podem obter vantagens competitivas significativas, destacando-se em um
mercado cada vez mais exigente e orientado pela velocidade e eficiência.

8 PROGRAMAÇÃO REATIVA, BLAZOR E FUTURO EM ASP.NET

A programação reativa é um paradigma que ultimamente tem ganhado espaço dentro do


desenvolvimento ASP.NET Core devido a sua abordagem focada na construção de aplicações mais
responsivas e escaláveis. Esse paradigma enfatiza a propagação de mudanças, permitindo que as
aplicações reajam de forma mais dinâmica e eficiente a eventos ou alterações no estado. No contexto
do ASP.NET Core, a programação reativa oferece uma maneira elegante de lidar com fluxos de dados
assíncronos e eventos, facilitando a criação de interfaces de usuário mais interativas e de back-ends
mais resilientes.

Lembrete

No tópico anterior, vimos em detalhes o React Native. Embora o


nome React Native sugira uma conexão com a programação reativa, sua
abordagem central não é baseada no paradigma de programação reativa da
mesma forma que frameworks e bibliotecas explicitamente reativas, como
o ReactiveX (RxJS para JavaScript, Rx.NET para .NET etc.). O React Native
utiliza o react para construir interfaces de usuário, que é declarativo e
baseado no conceito de componentes reativos que respondem a mudanças
de estado, mas não segue a programação reativa no sentido estrito de
manipulação de eventos e dados assíncronos através de observáveis e
operadores reativos, como veremos neste tópico.

Blazor, por outro lado, representa uma inovação significativa no desenvolvimento de aplicações
web com ASP.NET Core. Esse framework permite o desenvolvimento de interfaces de usuário ricas em
C#, possibilitando que os desenvolvedores utilizem suas habilidades existentes em .NET para construir
aplicações web sem depender de JavaScript. Blazor funciona como uma alternativa aos tradicionais
frameworks JavaScript e abre novas possibilidades para a criação de aplicações SPA (Single Page
Applications) robustas e interativas, utilizando a mesma base de código para o cliente e o servidor.

A capacidade de executar código .NET no lado do cliente, através do WebAssembly, é um dos


aspectos revolucionários do Blazor, oferecendo desempenho comparável ao código nativo e uma
experiência de desenvolvimento consistente. O WebAssembly (Wasm) é fundamental para o Blazor,
pois permite que código .NET seja executado no navegador a velocidades próximas ao código nativo.
Essa capacidade abre portas para aplicações web mais complexas e performáticas, permitindo aos
desenvolvedores utilizar todo o ecossistema .NET, incluindo bibliotecas e ferramentas, diretamente
no navegador.
218
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Olhando para o futuro do ASP.NET Core, espera-se uma continuidade no investimento em melhorias de
performance, segurança e escalabilidade, bem como uma maior integração com tecnologias emergentes.
A tendência é que a Microsoft continue a expandir as capacidades do ASP.NET Core, explorando, por
exemplo, a integração mais profunda com a nuvem, o desenvolvimento de microsserviços e a utilização
de contêineres. Além disso, espera-se que novas atualizações do Blazor e melhorias na programação
reativa tornem o desenvolvimento de aplicações ainda mais intuitivo e eficaz, acompanhando as
demandas por aplicações web mais complexas e interativas.

8.1 O que é programação reativa?

No universo do desenvolvimento de software, a programação reativa é um paradigma que tem


ganhado destaque, especialmente em aplicações que demandam alta responsividade e desempenho em
tempo real. Ele baseia-se na construção de aplicações que reagem a mudanças de estado ou eventos de
forma eficiente e controlada.

Ao contrário da programação imperativa tradicional, que segue uma sequência linear de comandos,
a programação reativa é construída em torno de fluxos de dados e propagação de mudanças,
permitindo que as aplicações respondam de maneira mais flexível e dinâmica às interações dos usuários
ou a outras fontes de eventos. No desenvolvimento com ASP.NET Core, a adoção da programação reativa
permite criar aplicações web robustas, escaláveis e altamente interativas em razão de sua capacidade
de gerenciar de forma eficaz os fluxos de dados assíncronos e os eventos, melhorando a experiência
do usuário final. Desse modo, ao utilizar bibliotecas e ferramentas que suportam o paradigma reativo,
como o Reactive Extensions (Rx), os desenvolvedores podem construir aplicações que reagem a eventos
em tempo real, como cliques de botões, entradas de dados ou mensagens de sistemas distribuídos, de
maneira mais intuitiva e declarativa.

Uma das principais vantagens da programação reativa no desenvolvimento ASP.NET Core é a sua
capacidade de lidar com cenários de alta concorrência e de grande volume de dados sem comprometer
o desempenho. Isso é particularmente útil em aplicações que requerem comunicações em tempo real,
como chats, jogos online ou aplicações financeiras, nos quais a latência baixa e a capacidade de processar
um grande número de eventos simultaneamente são críticas. Além disso, a natureza assíncrona da
programação reativa ajuda a evitar os bloqueios comuns em aplicações web tradicionais, promovendo
uma melhor utilização dos recursos do servidor e uma experiência de usuário mais suave.

Embora esse paradigma ofereça muitos benefícios, ele também apresenta desafios, especialmente
em termos de curva de aprendizado. Novos conceitos, como observáveis (observables), observadores
(observers) e operadores, podem ser diferentes dos padrões de desenvolvimento aos quais muitos
desenvolvedores estão acostumados. No entanto, uma vez superados esses obstáculos iniciais, a
programação reativa pode oferecer uma abordagem mais potente e flexível para o desenvolvimento de
aplicações web modernas.

219
Unidade IV

8.2 Observables e observers

A incorporação dos conceitos de observables e observers na programação com ASP.NET Core facilita
o manejo de dados assíncronos e eventos, permitindo que aplicações respondam de maneira mais
eficaz às interações dos usuários e a mudanças no ambiente de execução.

Observables podem ser entendidos como coleções de eventos ou valores ao longo do tempo.
Diferentemente das coleções tradicionais, como listas ou arrays, que são estáticas, os observables são
dinâmicos. Eles permitem modelar sequências de dados que evoluem, fornecendo um mecanismo
através do qual os produtores de dados podem emitir valores de forma assíncrona. No ASP.NET Core, isso
é particularmente útil para lidar com fluxos de dados que podem não estar imediatamente disponíveis,
como respostas de chamadas de API ou interações do usuário. A capacidade de tratar esses dados como
sequências que podem ser observadas torna a programação mais intuitiva e alinhada com a natureza
assíncrona das aplicações web modernas.

Os observers, por outro lado, são os consumidores desses dados. Eles monitoram os observables,
aguardando por novos eventos ou valores a serem emitidos. Quando um observable emite um valor,
este é automaticamente notificado a todos os seus observers inscritos. Essa inscrição cria um canal de
comunicação direto entre a fonte de dados e seu consumidor, permitindo que as aplicações reajam
de forma dinâmica a mudanças. Os observers implementam métodos específicos para tratar esses
eventos, como onNext para receber novos valores, onError para tratar erros e onCompleted para lidar
com a conclusão da sequência de dados.

A relação entre observables e observers é central para o modelo de programação reativa, oferecendo
uma abordagem declarativa para o tratamento de eventos, o que simplifica significativamente o
gerenciamento de estados e o fluxo de dados em aplicações ASP.NET Core, especialmente em cenários
complexos, que envolvem múltiplas fontes de dados e interdependências entre componentes da
aplicação. Ao abstrair a complexidade inerente à programação assíncrona e ao tratamento de eventos,
os desenvolvedores podem focar mais a lógica de negócios e a experiência do usuário, melhorando
a qualidade e a manutenibilidade do código. Ademais, o uso de observables e observers favorece a
composição e reutilização de código, já que operações comuns como filtragem, mapeamento e redução
podem ser facilmente aplicadas às sequências de dados, permitindo abstrações poderosas e expressivas.
Isso eleva o nível de abstração do código, tornando-o mais limpo e compreensível, e potencializa a
capacidade de reação das aplicações aos eventos, um aspecto crítico na criação de experiências de
usuário ricas e interativas.

Os observables e observers podem ser proveitosos em Web APIs para lidar com fluxos de dados
assíncronos, como chamadas de banco de dados ou integrações de serviços externos. Neste cenário,
pode-se usar observables para criar respostas assíncronas de chamadas a APIs externas ou operações
de banco de dados, permitindo que a API responda de forma reativa a eventos ou dados em tempo real.
Os observers seriam então usados para processar esses dados assim que eles se tornassem disponíveis,
enviando notificações push para os clientes da API ou atualizando caches.

220
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Vamos adotar um exemplo didático utilizando observables e observers para ilustrar como esses
conceitos funcionam na prática. Imagine que estamos desenvolvendo um sistema de notificações em
tempo real para um site de comércio eletrônico que alerte os usuários a respeito de ofertas especiais
assim que elas se tornem disponíveis. Primeiramente, definimos um observable que representará a fonte
de nossas ofertas especiais. Ele será responsável por “emitir” as ofertas especiais ao longo do tempo.
Podemos imaginar isso como um fluxo contínuo de eventos de ofertas:

using System;
using System.Reactive.Linq;

public class OfertasEspeciaisObservable :


IObservable<OfertaEspecial>
{
private List<IObserver<OfertaEspecial>> observers = new
List<IObserver<OfertaEspecial>>();

public IDisposable Subscribe(IObserver<Oferta


Especial> observer)
{
if (!observers.Contains(observer))
{
observers.Add(observer);
}
return new Unsubscriber<OfertaEspecial>(observe
rs, observer);
}
public void OfertaDisponivel(OfertaEspecial oferta)
{
foreach(var observer in observers)
{
observer.OnNext(oferta);
}
}

Em seguida, criamos um observer que será responsável por receber e processar as ofertas especiais
emitidas pelo observable. Este observer pode ser, por exemplo, um componente da aplicação responsável
por enviar notificações por e-mail aos usuários.

221
Unidade IV

using System;

public class NotificadorOfertas :


IObserver<OfertaEspecial>
{
public void OnCompleted()
{
Console.WriteLine(“Todas as ofertas foram notificadas.”);
}

public void OnError(Exception error)


{
Console.WriteLine($”Erro na notificação de ofertas:
{error.Message}”);
}
public void OnNext(OfertaEspecial value)
{
Console.WriteLine($”Nova oferta especial disponível:
{value.Descricao} com {value.Desconto}% de desconto!”);
// Aqui poderia ir o código para enviar o e-mail
}
}

Finalmente, conectamos nosso observer ao observable, permitindo que o observer seja notificado
sempre que uma nova oferta especial estiver disponível:

var ofertasEspeciais = new OfertasEspeciaisObservable();


var notificador = new NotificadorOfertas();

// Inscreve o notificador para receber ofertas especiais


var subscription = ofertasEspeciais.Subscribe(notificador);

// Emitindo novas ofertas especiais


ofertasEspeciais.OfertaDisponivel(new OfertaEspecial
{ Descricao = “TV 50 polegadas”, Desconto = 20 });
ofertasEspeciais.OfertaDisponivel(new OfertaEspecial
{ Descricao = “Notebook Gamer”, Desconto = 15 });

// Quando não houver mais ofertas para notificar, podemos


completar o Observable
subscription.Dispose();

Neste exemplo, OfertasEspeciaisObservable atua como a fonte, emitindo novas ofertas através do
método OfertaDisponivel. NotificadorOfertas é o observer que reage a estas ofertas, enviando e-mails
para os usuários. A comunicação entre o observable e o observer é estabelecida através da inscrição do

222
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

observer no observable. Esse fluxo demonstra a essência da programação reativa com esse paradigma
reativo, permitindo desenvolver aplicações ASP.NET Core que respondem de maneira eficiente e elegante
a eventos e dados dinâmicos.

8.3 Introdução ao Rx.Net

No desenvolvimento de aplicações modernas, a capacidade de lidar de forma eficaz com eventos


assíncronos e fluxos de dados é fundamental para criar experiências de usuário ricas e com alta
performance. A programação reativa é um paradigma que fornece ferramentas úteis para trabalhar
com esses cenários, e é aqui que o Rx.NET (Reactive Extensions for .NET) se destaca como uma biblioteca
essencial para os desenvolvedores.

O Rx.NET é uma implementação do padrão observer que permite aos desenvolvedores compor
e consumir sequências assíncronas de dados e eventos usando observables e observers, como já
explorado anteriormente. Esse modelo é útil em aplicações ASP.NET Core, no qual operações não
bloqueantes e a capacidade de reagir a eventos em tempo real podem melhorar significativamente
a escalabilidade e a experiência do usuário. O Rx.NET amplia as capacidades do framework .NET,
oferecendo uma abordagem coesa e poderosa para a programação assíncrona e baseada em eventos.

A biblioteca introduz conceitos como IObservable<T> e IObserver<T>, que são extensões naturais
dos padrões .NET existentes. IObservable<T> representa uma coleção de eventos futuros a que um
ou mais IObservers podem se inscrever. Quando um evento é emitido por um IObservable, todos os
seus observadores inscritos são notificados, permitindo-lhes reagir de forma adequada. Essa relação
entre observables e observers é dinâmica, permitindo operações complexas, como filtragem, seleção,
transformação e combinação de sequências de eventos de forma declarativa e concisa.

Uma das grandes vantagens do Rx.NET é a sua integração profunda com a linguagem C# e o
.NET Framework, permitindo aos desenvolvedores utilizar plenamente as funcionalidades da linguagem,
como LINQ (Language Integrated Query), para operar sobre fluxos de dados de forma expressiva e
intuitiva. Isso torna o código mais legível e fácil de manter, e também facilita a implementação de
lógicas complexas de processamento de eventos e dados.

Adicionalmente, o Rx.NET oferece uma solução para o tratamento de erros e exceções em operações
assíncronas. A biblioteca permite que os desenvolvedores encapsulem, propaguem e gerenciem erros
de forma eficaz ao longo das cadeias de observáveis, garantindo que as aplicações possam reagir de
maneira adequada a situações inesperadas sem comprometer a estabilidade ou a performance.

A adoção do Rx.NET em projetos ASP.NET Core altera a percepção sobre eventos, assincronicidade e
fluxos de dados porque habilita a criação de aplicações mais reativas, eficientes e fáceis de manter, ao
oferecer uma abordagem unificada para esses conceitos. Seja manipulando eventos de UI, realizando
chamadas HTTP não bloqueantes, ou integrando-se com APIs de streaming de dados em tempo real, o
Rx.NET fornece as ferramentas necessárias para enfrentar os desafios modernos do desenvolvimento de
aplicações web.

223
Unidade IV

Para ilustrar o uso do Rx.NET, vamos utilizar um exemplo simples, que simula o monitoramento
de um fluxo de dados – neste caso, preços de ações que mudam ao longo do tempo. Esse exemplo
demonstrará como podemos usar observables para criar um fluxo de dados, e observers para reagir a
eles. Vamos simular o recebimento de preços de ações e notificar o usuário quando o valor de uma ação
ultrapassar um certo limite.

Antes de começar, certifique-se de que o pacote Rx.NET (System.Reactive) esteja instalado em seu
projeto ASP.NET Core. Isso pode ser feito através do NuGet Package Manager. Primeiro, vamos criar um
observable que emite preços de ações. No mundo real, esses preços viriam de uma fonte de dados externa,
como uma API financeira, mas para este exemplo, vamos gerar mudanças de preço artificialmente:

using System;
using System.Reactive.Linq;

public class StockPriceGenerator


{
public static IObservable<StockPrice>
GeneratePrice(string symbol)
{
var random = new Random();
return
Observable.Interval(TimeSpan.FromSeconds(1))
.Select(_ => new StockPrice
{
Symbol = symbol,
Price = random.Next(100, 200) // Gera um preço
aleatório entre 100 e 200
});
}
}

public class StockPrice


{
public string Symbol { get; set; }
public int Price { get; set; }
}

Agora, vamos criar um observer que reage às mudanças de preço. Este observer estará interessado
em preços que excedam um certo limite e, quando isso acontecer, imprimirá uma mensagem de alerta:

using System;

public class StockPriceAlert : IObserver<StockPrice>


224
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

{
private string symbol;
private int priceThreshold;
public StockPriceAlert(string symbol, int priceThreshold)
{
this.symbol = symbol;
this.priceThreshold = priceThreshold;
}

public void OnCompleted()


{
Console.WriteLine($”Monitoramento concluído para {symbol}.”);
}

public void OnError(Exception error)


{
Console.WriteLine($”Erro no monitoramento de {symbol}:
{error.Message}”);
}

public void OnNext(StockPrice value)


{
if (value.Price > priceThreshold)
{
Console.WriteLine($”Alerta: {value.Symbol} atingiu
o preço de {value.Price}”);
}
}
}

Finalmente, vamos subscrever o nosso observer ao observable. Isso fará com que o observer seja
notificado sempre que o observable emitir um novo preço de ação:

class Program
{
static void Main(string[] args)
{
var symbol = “ACME”;
var priceThreshold = 150;
var observable = StockPriceGenerator.GeneratePrice(symbol);
var observer = new StockPriceAlert(symbol, priceThreshold);
var subscription = observable.Subscribe(observer);

225
Unidade IV

Console.WriteLine(“Pressione qualquer tecla para encerrar...”);


Console.ReadKey();

subscription.Dispose();
}
}

Esse exemplo demonstra o uso básico do Rx.NET para criar um sistema de monitoramento de
preços de ações simples. O observable StockPriceGenerator.GeneratePrice gera um fluxo de preços
de ações, enquanto o observer StockPriceAlert reage aos preços que excedem um determinado limite.
Ao subscrever o observer ao observable, definimos um canal de comunicação no qual os preços das
ações são monitorados e processados em tempo real. Esse padrão de design é extremamente útil para
aplicativos reais, em que eventos assíncronos e fluxos de dados precisam ser manipulados de forma eficaz.

8.4 Operadores comuns em Rx.Net

A riqueza e a flexibilidade dos operadores fornecidos pelo Rx.NET habilitam os desenvolvedores de


ASP.NET Core a construir aplicações complexas e reativas com um controle fino sobre como os dados são
produzidos, transformados, filtrados e combinados. Essa capacidade de manipular de forma declarativa
fluxos de dados assíncronos e eventos simplifica a programação reativa e abre portas para a criação de
sistemas mais responsivos, escaláveis e fáceis de manter.

Os operadores do Rx.NET podem ser categorizados com base em suas funcionalidades. Entre os
mais comumente utilizados, estão operadores de criação, transformação, filtragem, combinação e de
controle de erro. Cada categoria desempenha um papel fundamental na manipulação e no tratamento
de observables e na definição de como os observers reagem aos dados emitidos:

• Operadores de criação, como Observable.Create, Observable.Range e Observable.Interval são


usados para iniciar fluxos de dados. Eles permitem definir as condições iniciais de suas sequências
observáveis, estabelecendo a base para a emissão de eventos ou dados.

• Operadores de transformação, tal como Select e SelectMany, modificam os itens emitidos por
um observable. Select é usado para transformar cada item da sequência, enquanto SelectMany
é capaz de mesclar múltiplos observables resultantes da transformação de itens em uma única
sequência, facilitando o tratamento de cenários nos quais cada evento pode levar à geração de
múltiplos eventos derivados.

• Os operadores de filtragem, incluindo Where, Distinct e Take, permitem que apenas uma parte dos
dados emitidos seja passada para os observers. Por exemplo, Where é similar à cláusula WHERE
do SQL, permitindo aos desenvolvedores especificar uma condição para selecionar elementos
específicos de uma sequência. Isso é útil para ignorar dados irrelevantes ou fora do escopo desejado.

• Operadores de combinação, como Merge, Concat e CombineLatest, fornecem meios para unir dados
de múltiplos observáveis. Merge combina múltiplos observáveis em um único fluxo, enquanto
226
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Concat os concatena, preservando a ordem dos observáveis. CombineLatest, por outro lado, emite
um item sempre que qualquer um dos observables de entrada emitir um item, combinando o
último item emitido por cada observable em uma única emissão.

• Por fim, operadores de controle de erro, como Catch e Retry, são essenciais para o tratamento
de exceções em fluxos de dados assíncronos. Eles permitem aos desenvolvedores especificar
ações de recuperação, melhorando a robustez e a resiliência das aplicações ao enfrentarem
condições de erro.

Vamos explorar alguns exemplos práticos de uso de operadores comuns no Rx.NET em uma aplicação
ASP.NET Core. Esses exemplos, dispostos nos quadros 35, 36 e 37, demonstrarão como os operadores
podem ser usados para transformar, filtrar e combinar fluxos de dados de forma reativa.

Quadro 35

Exemplo 1: transformação com Select


using System;
using System.Reactive.Linq;

IObservable<int> numeros = Observable.Range(1, 5); //


Cria um observável que emite números de 1 a 5
IObservable<int> numerosTransformados = numeros.
Select(n => n * 10); // Transforma cada número,
Imagine que você tem um multiplicando por 10
fluxo de números e deseja
transformá-los, multiplicando numerosTransformados.Subscribe(
cada um por 10
onNext: Console.WriteLine, // Para cada item
emitido, imprime o resultado
onError: error =>
Console.WriteLine($”Erro: {error.Message}”),
onCompleted: () =>
Console.WriteLine(“Completo!”)
);

Quadro 36

Exemplo 2: filtragem com Where


IObservable<int> numeros =
Observable.Range(1, 10); // Cria um observável que
emite números de 1 a 10
IObservable<int> numerosPares =
numeros.Where(n => n % 2 == 0); // Filtra apenas
números pares
Suponha que você esteja
observando uma sequência numerosPares.Subscribe(
de números e queira apenas
os que são pares onNext: Console.WriteLine, // Imprime cada número
par
onError: error =>
Console.WriteLine($”Erro: {error.Message}”),
onCompleted: () =>
Console.WriteLine(“Completo!”)
);

227
Unidade IV

Quadro 37

Exemplo 3: combinação com CombineLatest


IObservable<long> intervaloRapido =
Observable.Interval(TimeSpan.FromSeconds(1)); //
Emite a cada 1 segundo
Vamos combinar fluxos IObservable<long> intervaloLento =
de dados de duas fontes Observable.Interval(TimeSpan.FromSeconds(2)); //
diferentes, emitindo um Emite a cada 2 segundos
resultado cada vez que
qualquer uma das fontes
emitir um novo item, IObservable<string> combinado =
combinando o último item intervaloRapido.CombineLatest(intervaloLento,
emitido por cada fonte (rapido, lento) => $”Rapido: {rapido}, Lento:
{lento}”);

combinado.Subscribe(Console.WriteLine);

Este útimo exemplo emitirá um novo valor a cada segundo, combinando o último valor emitido pelo
intervaloRapido com o último valor emitido pelo intervaloLento, mesmo que intervaloLento emita em
um intervalo diferente.

Esses exemplos demonstram a potência dos operadores no Rx.NET para manipular dados de
forma reativa em aplicações ASP.NET Core. Usando Select, podemos transformar facilmente os dados
emitidos por um observable. O operador Where nos permite filtrar esses dados, passando apenas os
valores que satisfazem uma determinada condição. Por fim, CombineLatest é um exemplo de como
podemos combinar dados de múltiplos observables, reagindo a cada nova emissão de qualquer um dos
observables‑fonte.

8.5 Integração do Rx.Net com ASP.NET

O Reactive Extensions for .NET oferece um conjunto de operadores e tipos para compor e consumir
sequências de eventos assíncronos de maneira declarativa (vide quadro 38). Sua integração em
aplicações ASP.NET Core é benéfica sobretudo em cenários que demandam tratamento de eventos
em tempo real, operações assíncronas complexas e comunicação entre componentes de forma
eficiente. Esses cenários incluem, mas não se limitam a sistemas de notificação em tempo real,
processamento de streams de dados e interações complexas de usuário em aplicações web.

228
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Quadro 38 – Operadores e tipos para compor e consumir sequências de eventos assíncronos

Observable.Create: cria um observable a partir de uma função assíncrona, permitindo emitir


notificações para os observadores manualmente
Criar Observable.Range: gera uma sequência de números dentro de um intervalo específico, emitindo cada
número sequencialmente
Observable.Interval: cria uma sequência de números emitidos em intervalos de tempo regulares
Select: transforma os itens emitidos por um observable aplicando uma função especificada a cada item
Transformar SelectMany: projeta cada elemento de uma sequência observável para um observable e mescla os
resultados em uma única sequência observável
Where: filtra os itens emitidos por um observable, emitindo apenas aqueles que satisfazem uma
condição especificada
Filtrar Distinct: suprime itens duplicados sequenciais em uma sequência observável
Take: emite apenas os primeiros n itens de um observable e, em seguida, completa
Merge: combina múltiplos observables em um, emitindo os itens assim que são emitidos por qualquer
um dos observable de entrada
Concat: concatena múltiplas sequências observables, emitindo os itens de uma sequência após a outra
Combinar sequência ser completada
CombineLatest: quando qualquer observable emite um item, emite um item que é uma combinação
dos últimos itens emitidos por cada observable
Catch: recupera-se de um erro em um observable substituindo-o com outro observable ou sequência
Erro
Retry: repete a subscrição ao observable-fonte quando ocorre um erro, tentando novamente

Ao integrar o Rx.NET com ASP.NET Core, desenvolvedores podem tirar vantagem de suas
funcionalidades reativas no back-end mas podem também facilitar interações no front-end. Por exemplo,
em uma Web API construída com ASP.NET Core, o Rx.NET pode ser utilizado para gerenciar fluxos de
dados de APIs externas, processando-os de forma assíncrona e reativa antes de servir ao cliente. Isso
melhora a performance ao evitar bloqueios desnecessários e simplifica a lógica de manipulação de erros
e retry patterns (padrões de tentativa), graças aos operadores reativos que o Rx.NET fornece.

Os retry patterns são estratégias de design de software usadas para determinar como e quando repetir
uma operação que falhou, na tentativa de obter sucesso em execuções subsequentes. Esse padrão pode
ser usado em situações nas quais as falhas podem ser transitórias, como em chamadas de rede, acessos a
bancos de dados, ou comunicações entre serviços, em que problemas temporários de conexão, timeouts,
ou falhas esporádicas de serviço podem ocorrer. O principal objetivo do retry pattern é aumentar a
resiliência da aplicação, permitindo que ela se recupere automaticamente de falhas temporárias, sem
intervenção humana.

O Rx.NET oferece suporte nativo através de operadores como Retry e RetryWhen. Esses operadores
permitem que os desenvolvedores implementem facilmente a lógica de retentativa em suas sequências
de observables, tratando de forma eficiente as operações assíncronas que podem falhar temporariamente.
Por exemplo, o operador Retry pode ser usado para repetir automaticamente uma subscrição ao
observable‑fonte se uma exceção for emitida, enquanto o RetryWhen permite um controle mais
sofisticado sobre as condições sob as quais a retentativa deve ocorrer, incluindo a implementação de
lógicas de backoff.

229
Unidade IV

No lado do servidor, a capacidade do Rx.NET de tratar eventos como coleções observáveis permite
uma abordagem mais intuitiva à lógica assíncrona, substituindo callbacks e promises por fluxos de dados
que podem ser facilmente filtrados, transformados e combinados, resultando em um código mais limpo,
modular e fácil de manter, especialmente em aplicações que lidam com uma grande quantidade de
operações assíncronas ou em tempo real. No mais, a integração do Rx.NET com ASP.NET Core facilita o
desenvolvimento de funcionalidades de backpressure, na qual o consumo de recursos pode ser ajustado
dinamicamente com base na capacidade de processamento e na demanda atual. Esse aspecto é crucial
para aplicações de alta performance e escalabilidade, permitindo que elas se adaptem a variações de
carga sem comprometer a estabilidade ou a experiência do usuário.

Para facilitar a integração, a comunidade e as bibliotecas auxiliares oferecem extensões e utilitários


que simplificam o uso do Rx.NET em projetos ASP.NET Core. Por exemplo, middlewares personalizados
podem ser desenvolvidos para tratar padrões de comunicação reativa, como WebSockets ou Server‑Sent
Events (SSE), utilizando observables para representar conexões e mensagens de forma reativa.

Em suma, a integração do Rx.NET com ASP.NET Core abre portas para um novo espectro de
possibilidades no desenvolvimento de aplicações web. Ela não apenas enriquece o ecossistema .NET
com padrões de design reativos, mas também promove uma maneira mais eficiente e expressiva de
construir aplicações responsivas e prontas para enfrentar os desafios de escalabilidade e performance
do mundo moderno.

8.6 Introdução ao Blazor

O Blazor representa uma revolução significativa na forma como os desenvolvedores constroem


aplicações web, permitindo-lhes usar C# e .NET para criar tanto o front-end quanto o back‑end de
suas aplicações. Essa abordagem unificada contrasta fortemente com o modelo tradicional, que
normalmente exige o uso de JavaScript para o desenvolvimento do lado do cliente. A introdução do
Blazor no ASP.NET Core oferece a capacidade de aproveitar o poder e a eficiência do .NET no navegador,
sem a necessidade de plugins adicionais ou transpilação de linguagens. Isso é possível graças ao
WebAssembly, uma tecnologia que permite a execução de código no navegador em uma velocidade
próxima à nativa. O Blazor utiliza o WebAssembly para rodar o código .NET no lado do cliente de uma
forma eficiente e segura, o que abre um novo mundo de possibilidades para o desenvolvimento de
aplicações ricas e interativas na web.

A arquitetura do Blazor é projetada para ser flexível e modular, oferecendo duas principais
modalidades de hospedagem: Blazor Server e Blazor WebAssembly. No modelo Blazor Server, a
lógica da aplicação é executada no servidor, com as interações do usuário sendo manipuladas por
uma conexão SignalR em tempo real. Esse modelo permite aplicações altamente dinâmicas com
mínimo tráfego de dados, mas depende da conexão constante com o servidor. Por outro lado, o
Blazor WebAssembly hospeda a aplicação inteiramente no navegador do cliente, permitindo uma
experiência de usuário mais fluida e reduzindo a carga sobre o servidor. Essa flexibilidade de escolha
entre execução no lado do servidor ou no cliente oferece aos desenvolvedores a liberdade de otimizar
suas aplicações de acordo com as necessidades do projeto.

230
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

A “conexão SignalR em tempo real” é uma tecnologia específica dentro do ecossistema .NET
que facilita a comunicação bidirecional entre o servidor e o cliente em aplicações web e móveis.
Desenvolvido pela Microsoft, o ASP.NET SignalR é um framework para adicionar funcionalidades
de web em tempo real a aplicações, o que permite que o servidor envie conteúdo para os clientes
instantaneamente, sem que ele precise solicitar explicitamente novos dados. Isso simplifica o processo
de construção de aplicações interativas que necessitam de atualizações em tempo real, como jogos
online, aplicativos de chat, sistemas de notificação em tempo real e dashboards que atualizam
dinamicamente dados. O SignalR utiliza várias técnicas de transporte de dados em segundo plano,
escolhendo automaticamente a melhor técnica disponível com base nas capacidades do cliente e do
servidor. Entre estas técnicas estão WebSockets, Server-Sent Events (SSE) e Long Polling.

O Blazor também se destaca por sua integração com o restante do ecossistema .NET, permitindo
que os desenvolvedores reutilizem bibliotecas e apliquem práticas de desenvolvimento consistentes
em toda a sua base de código. Ele favorece uma abordagem de desenvolvimento que é baseada em
componentes, em que a UI (user interface) é construída a partir de componentes reutilizáveis e
interativos que podem ser facilmente compartilhados e mantidos.

Essa abordagem aumenta a eficiência do desenvolvimento e melhora significativamente a


manutenibilidade e a escalabilidade das aplicações web. De fato, a introdução do Blazor no ecossistema
ASP.NET Core representa um avanço considerável na forma como as aplicações web são desenvolvidas,
oferecendo uma abordagem unificada que promete simplificar o desenvolvimento web ao mesmo
tempo em que abre novas possibilidades para a criação de aplicações interativas e de boa performance.
À medida que a tecnologia continua evoluindo, o Blazor se posiciona como uma peça‑chave na futura
paisagem do desenvolvimento web, prometendo transformar as expectativas e as práticas atuais do setor.

8.7 Construindo uma SPA com Blazor

Construir uma Single Page Application (SPA) com Blazor no Visual Studio 2022 é um processo
simplificado, graças aos templates pré-configurados e à integração do ambiente de desenvolvimento.
Neste exemplo, criaremos uma SPA básica que lista tarefas e permite ao usuário adicioná‑las. Usaremos
o Blazor WebAssembly, que executa o código .NET no navegador.

1. Crie um novo projeto

• Abra o Visual Studio 2022.

• Selecione “Criar um novo projeto”.

• Na caixa de pesquisa, digite Blazor e escolha o template “Blazor WebAssembly StandAlone App”
(vide figura 97). Clique em “Próximo”.

• Nomeie o projeto como BlazorSPA e clique em “Próximo”.

• Na tela “Informações Adicionais”, mantenha as configurações-padrão e clique em “Criar”.


231
Unidade IV

2. Estruture a aplicação

• Crie uma página simples, que liste tarefas e tenha um formulário para adicioná-las.

• No “Solution Explorer”, encontre a pasta “Pages”.

• Clique com o botão direito do mouse na pasta Pages, vá em “Adicionar” e depois em “Razor
Component” (figura 98) e nomeie o componente como Todo.razor (figura 99).

Figura 97 – Criando um projeto Blazor

Figura 98 – Adicionando um componente Razor

232
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Figura 99 – Nomeando o componente Razor

3. Adicione um Markup e Código ao Todo.razor

• Abra o arquivo “Todo.razor” e substitua o conteúdo pelo seguinte código:

@page “/todo”

<h3>Lista de tarefas</h3>

@if (todos == null)


{
<p><em>Carregando...</em></p>
}
else
{
<ul>
@foreach (var todo in todos)
{
<li>@todo</li>
}
</ul>

<input type=”text” @bind=”newTodo” />


<button @onclick=”AddTodo”>Adicionar</button>
}

233
Unidade IV

@code {
private List<string> todos = new List<string>();
private string newTodo;

protected override async Task OnInitializedAsync()


{
// Simulate async data loading
await Task.Delay(500);
todos.AddRange(new[] { “Tarefa 1”, “Tarefa 2”, “Tarefa 3” });
}

private void AddTodo()


{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(newTodo);
newTodo = string.Empty; // Limpar o input após adicionar
}
}
}

• Esse código cria uma interface simples para exibir uma lista de tarefas e um campo de entrada
para adicionar novas tarefas à lista. O método OnInitializedAsync simula o carregamento de
dados assíncronos.

4. Atualize o NavMenu

• Abra o arquivo _Imports.razor e adicione a seguinte linha no topo para importar a namespace das
suas páginas, se necessário:

@using BlazorSPA.Pages

• Abra o arquivo Layout/NavMenu.razor.

• Adicione o seguinte item de menu para a sua página Todo dentro da seção <div class=
”@NavMenuCssClass nav-scrollable” @onclick=”ToggleNavMenu”>:

<li class=”nav-item px-3”>


<NavLink class=”nav-link” href=”todo”>
<span class=”oi oi-list-rich” aria-hidden=”true”></
span> Todo List
</NavLink>
</li>

234
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

5. Execute a aplicação

• Pressione F5 para construir e executar a aplicação.

• A aplicação será aberta em um navegador (figura 100). Navegue até a rota/todo (ou clique no link
Todo List, conforme destaque na figura 101) para ver sua lista de tarefas (figura 99) e adicionar
novas tarefas (figura 102).

Figura 100 – Executando a SPA Blazor

Figura 101 – Exibindo a lista de tarefas

235
Unidade IV

Figura 102 – Adicionando uma nova tarefa

• O resultado da inclusão pode ser visto na figura 103.

Figura 103 – Nova tarefa incluída na lista

Lembrete

A confusão entre Razor e Blazor é comum, mas é importante esclarecer


a relação entre os dois.

Como vimos anteriormente, Razor é uma sintaxe de marcação para


incorporar código baseado em C# dentro de páginas HTML, permitindo a
criação de páginas web dinâmicas com ASP.NET. Blazor, como acabamos

236
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

de ver, é um framework que utiliza a sintaxe Razor para permitir que


desenvolvedores escrevam aplicações web interativas usando C# em
vez de JavaScript.

Blazor pode ser visto como uma extensão do Razor, especificamente


adaptada para o desenvolvimento de aplicações web ricas (Single Page
Applications – SPAs) que rodam no navegador utilizando WebAssembly,
além de suportar modelos de renderização no lado do servidor. Portanto,
quando se diz que o código está em Razor no contexto de Blazor, isso está
tecnicamente correto, pois o Blazor utiliza a sintaxe Razor. No entanto, o
termo Blazor refere-se mais especificamente ao framework e ao modelo de
execução – seja ele Blazor WebAssembly (executando C# no navegador),
seja ele Blazor Server (executando C# no servidor e interagindo com o
navegador via SignalR). Ambos usam arquivos com a extensão .razor e a
sintaxe Razor para definir componentes e páginas.

8.8 Blazor WebAssembly versus Blazor Server

Ambos – Blazor WebAssembly e Blazor Server – compartilham a mesma base de desenvolvimento,


usando componentes Razor para construir a UI, mas divergem significativamente em como e onde
o código é executado, influenciando diretamente a performance, a escalabilidade e a experiência do
usuário final.

Blazor WebAssembly é uma abordagem mais moderna entre os dois, que permite que o código .NET
seja executado diretamente no navegador através do WebAssembly, possibilitando uma experiência
de usuário rica e fluida, com tempos de resposta rápidos e redução na carga sobre o servidor,
uma vez que a maior parte do processamento ocorre no lado do cliente. Além disso, aplicações Blazor
WebAssembly podem ser servidas de forma estática a partir de qualquer servidor web ou serviço de
hospedagem de arquivos, o que simplifica a implantação e reduz os custos de infraestrutura. No entanto,
essa abordagem também apresenta desafios, incluindo tempos iniciais de carregamento potencialmente
mais longos, devido ao download do runtime .NET e da aplicação para o navegador, e limitações de
acesso a recursos do servidor em tempo real sem comunicação adicional via APIs ou SignalR.

Blazor Server, por outro lado, oferece uma arquitetura diferente, na qual o código .NET é executado
no servidor e as interações do usuário com a interface são gerenciadas por uma conexão SignalR
persistente e em tempo real. Isso resulta em tempos de carregamento inicial rápido e acesso imediato
aos recursos do servidor, tornando mais fácil construir aplicações que interagem intensivamente com
bancos de dados ou outros serviços no lado do servidor. Contudo, a dependência de uma conexão
constante e de baixa latência com o servidor pode afetar a experiência do usuário em condições de rede
adversas. Além disso, enquanto a escalabilidade pode ser gerenciada com tecnologias de balanceamento
de carga e instâncias de servidor adicionais, aplicações Blazor Server podem exigir mais recursos de
servidor e infraestrutura quando comparadas à abordagem WebAssembly.

237
Unidade IV

O Blazor WebAssembly pode ser considerado uma solução ideal para o desenvolvimento de
Progressive Web Apps (PWAs) por sua capacidade de oferecer uma experiência semelhante à de aplicações
nativas, com o benefício adicional de funcionamento offline. Sua arquitetura client‑side proporciona aos
usuários uma experiência contínua e integrada, independentemente da conectividade com a internet.
Além disso, ele se mostra extremamente eficaz para o desenvolvimento de ferramentas interativas
e jogos executados diretamente no navegador do cliente. A capacidade de realizar o processamento
no lado do cliente minimiza a latência, oferecendo uma resposta quase instantânea às interações do
usuário, um aspecto vital para jogos e aplicações que demandam alta interatividade, em que cada
milissegundo de atraso pode prejudicar significativamente a experiência do usuário.

Para portais de clientes e dashboards, o Blazor WebAssembly também é uma escolha acertada, pois
a distribuição do processamento permite não apenas uma redução da carga sobre os servidores, mas
também garante uma experiência de usuário fluida e responsiva. Essas características são essenciais
para dashboards que exibem dados em tempo real ou portais de clientes em que a performance e a
responsividade são prioritárias.

Já o Blazor Server é especialmente vantajoso para aplicações empresariais internas, já que


frequentemente elas necessitam de acesso direto e seguro a recursos no servidor, algo que a ferramenta
facilita por sua arquitetura baseada em servidor. Além disso, em ambientes empresariais, é comum
contar com uma conexão de rede estável e confiável, mitigando uma das principais limitações do Blazor
Server, a dependência de uma conexão persistente com o servidor.

Quando o assunto é segurança, o Blazor Server novamente se destaca. Aplicações com requisitos de
segurança elevados se beneficiam do controle rigoroso sobre o ambiente de execução e do acesso direto
a recursos de segurança no servidor, características intrínsecas ao Blazor Server. Essa abordagem permite
uma gestão de segurança mais forte e centralizada, essencial para aplicações que manipulam dados
sensíveis ou realizam operações críticas. Finalmente, para a prototipagem rápida e aplicações de baixo
tráfego, o Blazor Server oferece uma solução eficiente. A simplicidade e a rapidez no desenvolvimento,
aliadas à menor necessidade de otimização de performance no lado do cliente, tornam o Blazor Server
ideal para projetos que precisam ser desenvolvidos e lançados rapidamente, sem as preocupações com
escalabilidade e performance que acompanham aplicações de maior porte.

A escolha entre Blazor WebAssembly e Blazor Server não é apenas uma questão de preferência
técnica, mas também uma decisão estratégica que deve considerar as necessidades da aplicação, o
perfil dos usuários finais e os recursos de infraestrutura disponíveis. Por exemplo, uma aplicação que
requer interação intensa com o servidor e tem um público-alvo com boas conexões de internet pode
se beneficiar da arquitetura Blazor Server, enquanto uma aplicação que precisa funcionar offline ou
com mínima comunicação com o servidor pode ser mais propícia ao uso do Blazor WebAssembly.
O quadro 39 destaca as principais diferenças entre eles.

238
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Quadro 39 – Comparativo entre Blazor WebAssembly e Blazor Server


Critério Blazor WebAssembly Blazor Server
No navegador do cliente, usando No servidor, as interações do usuário são
Execução do código WebAssembly gerenciadas via SignalR
Potencialmente mais lento, pois o runtime Rápido, pois apenas o HTML mínimo e os
Carregamento .NET e a aplicação precisam ser baixados para assets estáticos são necessários para o
inicial o navegador carregamento inicial
Concentrado no servidor, pode exigir
Distribuído, com processamento ocorrendo no
Uso de recursos mais recursos do servidor à medida que o
cliente. Reduz a carga no servidor número de usuários aumenta
Direto, com acesso fácil a bancos de dados
Acesso a dados Através de APIs ou serviços externos e outros recursos do servidor
Funciona offline, uma vez que os assets Requer uma conexão constante e estável
Conectividade necessários estão carregados com o servidor devido ao uso de SignalR
Escala facilmente, pois a maioria do Pode ser desafiador escalar devido
Escalabilidade à manutenção do estado e ao
processamento é feita no cliente gerenciamento de conexões em tempo real
A segurança deve ser considerada nas Mais fácil de gerenciar a segurança, pois o
Segurança chamadas de API, pois o código roda no código roda em um ambiente controlado
ambiente não confiável do cliente no servidor

Saiba mais

O livro Blazor for ASP.NET Web Forms developers é uma excelente opção
para desenvolvedores que já têm experiência com ASP.NET Web Forms e
desejam migrar ou expandir seus conhecimentos para o Blazor. Ele aborda
conceitos fundamentais do Blazor, comparações detalhadas entre Web Forms
e Blazor e oferece orientações práticas sobre como fazer a transição para
aplicações modernas com Blazor. O livro cobre tanto Blazor Server quanto
Blazor WebAssembly.

Já o livro Programming Blazor: building web applications in .NET é


voltado para desenvolvedores que buscam uma compreensão profunda de
como construir aplicações interativas e reativas com Blazor. O autor, um
contribuidor ativo da comunidade Blazor, compartilha sua expertise em
exemplos práticos, explicando como aproveitar todo o potencial do Blazor
para criar aplicações web ricas em .NET. O livro detalha desde os conceitos
básicos até técnicas avançadas, incluindo gerenciamento de estado,
integração de APIs e melhores práticas para desempenho e escalabilidade.

ROTH, D. et al. Blazor for ASP.NET Web Forms Developers. Redmont:


Microsoft, 2023.

HIMSCHOOT, P. Programming Blazor: building web applications in .NET.


New York: Apress, 2020.

239
Unidade IV

8.9 Multithreading e concorrência em ASP.NET

A concorrência em ASP.NET Core pode ser entendida como a capacidade do aplicativo de lidar com
várias solicitações de clientes simultaneamente. Em vez de processar cada solicitação sequencialmente,
o que poderia levar a ineficiências significativas e latências elevadas, o ASP.NET Core utiliza threads, que
são sequências de execução independentes, permitindo a execução de várias tarefas ao mesmo tempo
ou em paralelo. Esse modelo de execução simultânea é essencial em ambientes de servidor de alta
carga, onde o tratamento eficiente de solicitações concorrentes determina a capacidade de resposta e
a escalabilidade do aplicativo.

Multithreading, desse modo, refere-se à técnica de criar, gerenciar e sincronizar threads dentro de
um processo. No contexto do ASP.NET Core, o multithreading é empregado para melhorar o desempenho
de aplicações, ao dividir tarefas computacionalmente intensivas em múltiplos threads que podem ser
executados em paralelo, aproveitando assim os múltiplos núcleos de processamento disponíveis na
maioria dos servidores modernos, o que facilita operações de I/O (entrada/saída), como acessos a banco
de dados ou chamadas a APIs web, nas quais a espera pela conclusão da operação pode ser otimizada,
permitindo que outros threads processem outras solicitações ou tarefas em paralelo.

Contudo, a sincronização entre threads é um aspecto crítico para evitar condições de corrida,
deadlocks e outros problemas de concorrência que podem afetar a estabilidade e a segurança do
aplicativo. Uma condição de corrida ocorre quando o resultado de um programa depende da sequência
ou do tempo de execução de eventos concorrentes, tais como threads, que operam sobre dados
compartilhados. Se esses eventos não são adequadamente sincronizados, um thread pode interferir no
trabalho de outro, levando a resultados inesperados ou incorretos. Por exemplo, se dois threads tentam
incrementar simultaneamente o valor de uma mesma variável sem sincronização adequada, é possível
que um dos incrementos seja “perdido”, resultando em um valor final incorreto.

Deadlocks ocorrem quando dois ou mais threads ficam bloqueados indefinidamente, esperando um
pelo outro para liberar recursos. Isso geralmente acontece em situações em que cada thread segura
um recurso e aguarda a liberação de outro, criando um ciclo de dependências que impede qualquer
avanço. Imagine dois threads: o primeiro adquire o Recurso A e depois tenta adquirir o Recurso B,
enquanto o segundo já adquiriu o Recurso B e tenta adquirir o Recurso A: ambos ficam bloqueados
esperando que o outro libere o recurso que necessitam, resultando em um impasse. Outros problemas
de concorrência incluem:

• Starvation (inanição): ocorre quando um ou mais threads de baixa prioridade são impedidos
de executar porque os threads de alta prioridade continuam a consumir todos os recursos de
processamento disponíveis.

• Live locks: similar ao deadlock, em que dois ou mais threads não estão bloqueados, mas ainda
assim não conseguem avançar porque cada um repete a mesma operação em resposta às ações
do outro, anulando seu progresso.

240
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

• Priority inversion: acontece quando um thread de baixa prioridade segura um recurso necessário
por um thread de alta prioridade. Se o thread de baixa prioridade é preterido por threads de
prioridade intermediária, então o thread de alta prioridade pode ser indiretamente preterido por
um período inesperadamente longo.

O ASP.NET Core oferece várias abstrações e ferramentas, como semáforos, locks e a biblioteca TPL
(Task Parallel Library), para ajudar os desenvolvedores a gerenciar esses desafios, permitindo a criação
de código concorrente, que é tanto eficiente quanto seguro. Semáforos são uma das abstrações mais
fundamentais para controle de concorrência. Eles funcionam como contadores que são utilizados para
gerenciar o acesso a um número limitado de recursos compartilhados. Quando um thread deseja acessar
um recurso, ele deve primeiro adquirir o semáforo; se o semáforo indicar que nenhum recurso está
disponível (isto é, seu valor é zero), o thread será bloqueado até que um recurso seja liberado. Esse
mecanismo permite controlar quantos threads podem acessar simultaneamente um recurso específico
ou seção crítica do código, prevenindo a sobrecarga de recursos e possíveis condições de corrida.

Locks, ou bloqueios, oferecem um meio mais direto de sincronização, garantindo que apenas um
thread por vez execute um bloco de código que acessa recursos compartilhados. Ao entrar em uma
seção crítica, um thread adquire o lock e, ao sair, o libera. Se outro thread tentar entrar na seção crítica
enquanto o lock estiver ativo, ele será bloqueado até que o lock seja liberado. Isso impede que múltiplos
threads modifiquem dados compartilhados de forma simultânea, evitando inconsistências e garantindo
a integridade dos dados.

Por fim e não menos importante, a Task Parallel Library (TPL) configura-se como uma evolução
na criação de programas concorrentes e paralelos em .NET. Ela abstrai a complexidade inerente à
programação multithreaded, fornecendo um modelo baseado em tarefas poderoso porém fácil de
usar. A TPL permite aos desenvolvedores expressar operações potencialmente complexas de concorrência
e paralelismo de maneira simples e declarativa, através de tasks que representam operações assíncronas.
A biblioteca gerencia automaticamente o agendamento de tarefas e a alocação de threads, permitindo
que os desenvolvedores se concentrem na lógica de aplicação sem se preocupar com os detalhes de
baixo nível do gerenciamento de threads.

Não obstante, o ASP.NET Core adota o modelo assíncrono de programação como um padrão de
design recomendado para operações de I/O. Usando as palavras-chave async e await, os desenvolvedores
podem escrever um código assíncrono que é visualmente limpo e fácil de ler, enquanto aproveitam o não
bloqueio de I/O e a escalabilidade. Desse modo, as aplicações ASP.NET Core podem atender a um número
maior de solicitações com menos threads do sistema, otimizando o uso de recursos e melhorando a
capacidade de resposta da aplicação.

8.10 Tendências em desenvolvimento web com ASP.NET

Neste cenário de rápida evolução em que vivemos, várias tendências emergentes prometem moldar
o futuro do ASP.NET e do desenvolvimento web como um todo. A primeira tendência promissora é a
maior integração com a inteligência artificial (IA) e o aprendizado de máquina (ML). Com o avanço
dessas tecnologias, espera-se que o ASP.NET Core facilite ainda mais a integração de modelos de IA e ML,
241
Unidade IV

permitindo que desenvolvedores implementem soluções inteligentes com eficiência. Isso poderia incluir
desde chatbots até personalização avançada de interfaces de usuário, análise preditiva e processamento
de linguagem natural (PLN).

Chatbots e o PLN são componentes-chave na interação automatizada com usuários, permitindo


que as aplicações entendam e respondam a entradas de texto ou voz de maneira natural. No contexto
do ASP.NET Core, desenvolvedores podem integrar APIs de terceiros, como o GPT (Generative Pretrained
Transformer) da OpenAI, para criar chatbots sofisticados. Isso é possível através de chamadas HTTP a estas
APIs, que enviam solicitações de texto e recebem respostas que podem ser processadas e apresentadas
aos usuários. A integração com essas tecnologias permite o desenvolvimento de chatbots que podem
lidar com diversas tarefas, desde o suporte ao cliente até a assistência pessoal, com boa compreensão e
resposta natural à linguagem humana.

Destaca-se que a personalização avançada de interfaces de usuário é outra área na qual o


ASP.NET Core e a IA/ML encontram um terreno comum. Utilizando análise de dados e aprendizado de
máquina, é possível adaptar a experiência do usuário com base em seus comportamentos, preferências
e interações. A análise preditiva envolve o uso de dados históricos e algoritmos de ML para prever
resultados. No ASP.NET Core, isso pode ser implementado pela integração com plataformas de análise
preditiva ou bibliotecas de ML, como ML.NET, uma biblioteca de aprendizagem de máquina da Microsoft
projetada para .NET. Com ela, os desenvolvedores podem criar modelos de ML que podem ser treinados,
avaliados e consumidos diretamente em aplicações ASP.NET Core, permitindo funcionalidades como
previsão de tendências de mercado, comportamento do usuário e muito mais.

A computação em nuvem já é uma parte integral do desenvolvimento web, mas sua importância
continuará crescendo, especialmente com o advento de serviços de computação sem servidor
(serverless computing). O ASP.NET Core está se posicionando para tirar pleno proveito dessa tendência,
oferecendo suporte aprimorado para arquiteturas sem servidor, o que permitirá aos desenvolvedores
construir aplicações mais escaláveis e de menor custo, sem a complexidade de gerenciar a infraestrutura
de servidores.

Outra área de inovação contínua a ser acentuada é o desenvolvimento de


Progressive Web Apps (PWAs) com ASP.NET Core. Embora já seja uma prática atual, espera-se que
os PWAs ganhem ainda mais recursos e capacidades, aproximando-se da experiência e funcionalidade
dos aplicativos nativos. Isso inclui melhorias em áreas como desempenho offline, notificações push e
sincronização em segundo plano, oferecendo uma experiência de usuário ainda mais rica e engajadora.
As PWAs introduzem um conjunto de tecnologias web modernas que permitem que aplicações web
sejam “instaladas” nos dispositivos dos usuários, funcionem offline, enviem notificações push e acessem
recursos do dispositivo, como câmera e geolocalização, sem a necessidade de passar pelas lojas de
aplicativos. Essas características são alcançadas pelo uso de service workers, manifestos da aplicação
web e APIs modernas da web, que, juntos, proporcionam uma experiência de usuário fluida, rápida
e envolvente.

242
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

A segurança sempre será uma preocupação premente e, em breve, veremos o ASP.NET Core
incorporar abordagens mais avançadas para segurança e privacidade dos dados. Isso pode envolver
a adoção de tecnologias de blockchain para transações seguras e verificáveis, bem como técnicas
mais sofisticadas de criptografia e autenticação, garantindo que as aplicações sejam seguras contra
ataques cibernéticos e em conformidade com regulamentações globais de privacidade de dados. Além
disso, a adoção de padrões e protocolos mais recentes para a web, como HTTP/3, promete melhorar
significativamente a performance e a eficiência das aplicações ASP.NET Core. Isso será fundamental para
suportar a crescente demanda por aplicações web de alta performance, capazes de lidar com grandes
volumes de dados em tempo real.

Finalmente, a evolução contínua da experiência do desenvolvedor (DX) no ASP.NET Core,


com ferramentas e frameworks mais intuitivos, colaborativos e eficientes, facilitará ainda mais o
desenvolvimento rápido e ágil de aplicações web, o que pode incluir melhorias na integração com IDEs,
ferramentas de diagnóstico e monitoramento em tempo real e recursos avançados de debugging.

O futuro do desenvolvimento web com ASP.NET Core é promissor, com avanços significativos
previstos em inteligência artificial, computação em nuvem, segurança, performance e experiência do
desenvolvedor. Essas tendências definirão a próxima geração de aplicações web, oferecendo experiências
de usuário sem precedentes e abrindo novas possibilidades para desenvolvedores e empresas.

8.11 Ferramentas e extensões úteis

O desenvolvimento com ASP.NET Core é amplamente reconhecido por sua flexibilidade, performance
e por ser open-source, facilitando a construção de aplicações web modernas e escaláveis. Neste contexto,
o uso eficiente de ferramentas e extensões otimiza o processo de desenvolvimento, garantindo a maior
produtividade dos desenvolvedores, além da qualidade do software produzido.

O próprio Visual Studio, uma das principais IDEs (Integrated Development Environments) para
desenvolvimento .NET, é frequentemente elogiado por sua integração profunda com ASP.NET Core. Ele
oferece recursos como IntelliSense, depuração poderosa e a capacidade de gerenciar dependências de
forma eficaz, tornando o ciclo de desenvolvimento mais rápido e menos propenso a erros.

A extensão do Visual Studio para Git facilita ainda mais o controle de versão, um aspecto
vital para a colaboração em projetos de desenvolvimento de software. Temos também o
Visual Studio Code (VS Code), que surge como uma alternativa leve, mas igualmente eficiente,
especialmente apreciada em ambientes de desenvolvimento que não se limitam ao Windows. Com
um vasto ecossistema de extensões, o VS Code pode ser personalizado para se adequar a praticamente
qualquer fluxo de trabalho de desenvolvimento. Extensões como C# for Visual Studio Code e .NET Core
Test Explorer ampliam significativamente suas funcionalidades, permitindo uma edição eficiente de
código, além de suportar testes unitários e de integração diretamente dentro da IDE.

Ferramentas de linha de comando, como o .NET CLI (Command Line Interface), são indispensáveis
para automação e integração contínua. Elas permitem que os desenvolvedores realizem tarefas como
criação de projetos, adição de pacotes e execução de testes diretamente do terminal, o que é útil em
243
Unidade IV

ambientes de desenvolvimento que adotam práticas DevOps. Não podemos deixar de mencionar as
extensões para browsers, tais como o Browser Link, que sincroniza a atualização de páginas web
com o código-fonte em ASP.NET Core e também são fundamentais para melhorar a experiência de
desenvolvimento. Essa ferramenta permite que os desenvolvedores vejam imediatamente o impacto
de suas alterações no código, sem a necessidade de recarregar manualmente a página, agilizando
significativamente o ciclo de feedback.

No ecossistema ASP.NET Core, vimos que o NuGet desempenha um papel central como gerenciador
de pacotes, facilitando a inclusão de bibliotecas e ferramentas de terceiros nos projetos. Há inúmeros
pacotes NuGet disponíveis que oferecem funcionalidades adicionais, desde autenticação e segurança até
manipulação de dados e serviços de aplicação, o que permite aos desenvolvedores construir aplicações
robustas e com recursos ricos.

Cita-se ainda o Rider da JetBrains, que é uma ótima IDE cross-platform para
desenvolvimento .NET que se destaca por sua performance e recursos. Com suporte completo
para desenvolvimento em .NET, ASP.NET, .NET Core, Xamarin, entre outros, o Rider oferece uma série
de funcionalidades, como refatoração de código, navegação eficiente e integração com sistemas de
controle de versão. A ferramenta inclui um bom depurador e um test runner integrado, que facilitam a
identificação e a correção de erros, além do suporte a bancos de dados e SQL.

Por fim, vale a pena mencionar o Postman, uma ferramenta essencial para desenvolvedores
que trabalham com APIs RESTful, uma prática comum em projetos ASP.NET Core. Ele permite aos
desenvolvedores testar APIs, visualizar respostas, gerar código de chamadas e colaborar com outros
membros da equipe no design e teste de APIs. Ele também ajuda a garantir que as APIs desenvolvidas
sejam robustas, eficientes e funcionem conforme o esperado em diferentes cenários.

O Swagger e o Postman são duas ferramentas prestigiadas usadas no desenvolvimento de APIs,


mas servem a propósitos distintos e, em muitos casos, complementares. Enquanto o Swagger foca
mais o estágio inicial de design da API, documentação interativa e especificação, o Postman é mais
voltado para o teste, exploração e colaboração pós-design da API. Assim, o Swagger é excelente para
definir e documentar a API de maneira que seja clara e interativa para todos os stakeholders, enquanto
o Postman é uma ferramenta excelente para desenvolvedores e testadores explorarem essas APIs,
realizarem testes detalhados e desenvolverem um entendimento profundo do comportamento da API
em diferentes condições.

244
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Resumo

O desenvolvimento de aplicações móveis tem experimentado um


crescimento sem precedentes, impulsionado pela demanda contínua por
soluções tecnológicas que combinam funcionalidade, escalabilidade e
eficiência. React Native, uma inovação do Facebook, tem se destacado
nesse contexto, oferecendo aos desenvolvedores a possibilidade de criar
aplicações móveis usando JavaScript e React, uma biblioteca focada
na construção de interfaces de usuário. A principal vantagem do React
Native reside em sua capacidade de compilar o mesmo código‑fonte para
plataformas nativas como iOS e Android, permitindo que desenvolvedores
utilizem suas competências preexistentes em JavaScript para produzir
aplicativos com experiências de usuário comparáveis às construídas em
linguagens nativas. Além disso, a tecnologia promove um desenvolvimento
mais ágil com funcionalidades como o hot reloading, que otimiza o processo
de visualização de alterações em tempo real.

A integração entre ASP.NET Core e React Native é destacada como


uma abordagem potente para o desenvolvimento móvel, combinando um
back-end robusto com um front-end responsivo e imersivo. Essa sinergia
capacita as equipes de desenvolvimento a criar soluções móveis completas,
que satisfazem as necessidades funcionais dos usuários finais e oferecem
uma experiência de usuário rica e envolvente. A capacidade cross‑platform
do React Native e a eficiência de desenvolvimento oferecem robustez e
funcionalidades de segurança do ASP.NET Core, e são fundamentais para
o desenvolvimento sustentável de aplicações que atendem às crescentes
expectativas do mercado.

Além da construção de interfaces e da integração entre front-end e


back-end, vimos que a autenticação e a segurança são aspectos críticos
no desenvolvimento de aplicativos móveis, especialmente em um cenário
tecnológico que evolui rapidamente. A autenticação, essencial para
personalizar a experiência do usuário e restringir o acesso a recursos
sensíveis, e a segurança, que abrange a proteção de dados em trânsito e
armazenados, são pilares para construir aplicações confiáveis e seguras.
ASP.NET Core se destaca ao oferecer funcionalidades integradas de
segurança e autenticação, facilitando a implementação de práticas
eficientes de segurança sem sacrificar a eficiência do desenvolvimento.

Já o deploy de aplicações construídas com React Native e ASP.NET Core


representa um desafio significativo, exigindo uma atenção meticulosa à
configuração do ambiente de produção, ao empacotamento do aplicativo

245
Unidade IV

e à comunicação eficiente entre o front-end e o back-end. Ferramentas e


práticas de DevOps são fundamentais para automatizar e otimizar este
processo, assegurando que o aplicativo mantenha sua estabilidade,
segurança e atualização pós-lançamento. Além disso, a otimização de
performance, tanto do lado do servidor quanto do cliente, é capaz
de proporcionar uma experiência de usuário ágil e satisfatória, destacando
a importância de uma abordagem holística e integrada ao desenvolvimento
de aplicações móveis modernas.

Apresentamos uma análise detalhada sobre as tendências e inovações


no desenvolvimento de aplicações web utilizando ASP.NET Core, com ênfase
especial na programação reativa e no framework Blazor. O paradigma da
programação reativa foi destacado como uma abordagem fundamental
para criar aplicações web responsivas e escaláveis, focando a manipulação
eficiente de eventos e dados assíncronos. Essa metodologia permite aos
desenvolvedores lidar com fluxos de dados de maneira mais intuitiva e
eficaz, especialmente em cenários de alta concorrência e volume de dados.
Neste cenário, o Blazor surge como uma inovação significativa, permitindo
o desenvolvimento de interfaces de usuário ricas diretamente em C#,
sem depender de JavaScript, o que representa um avanço considerável na
construção de Single Page Applications (SPAs) utilizando WebAssembly para
executar código .NET no navegador. A flexibilidade oferecida pelo Blazor em
termos de hospedagem no lado do servidor (Blazor Server) ou no cliente
(Blazor WebAssembly) abre novas possibilidades para o desenvolvimento
web, enfatizando a importância da escolha de tecnologia baseada nas
necessidades do projeto e na experiência do usuário final.

O futuro do ASP.NET Core é contemplado com otimismo, antecipando


a integração com tecnologias emergentes, como inteligência artificial (IA)
e aprendizado de máquina (ML), além da maior adoção da computação
em nuvem e dos Progressive Web Apps (PWAs). Tais avanços prometem
enriquecer ainda mais o ecossistema de desenvolvimento web, permitindo
a criação de aplicações mais inteligentes, eficientes e adaptáveis às
demandas modernas de desempenho, segurança e escalabilidade.

Finalmente, esta unidade abordou a importância de ferramentas


e extensões no aprimoramento da produtividade e eficácia no
desenvolvimento com ASP.NET Core. Ferramentas como Visual Studio e VS
Code, com o .NET CLI e extensões para navegadores, facilitam a gestão
de projetos, automação, testes e depuração. A disponibilidade de muitos
pacotes NuGet e a integração com tecnologias de controle de versão como
Git complementam o ecossistema, destacando a flexibilidade e robustez do
ASP.NET Core como uma plataforma de desenvolvimento web líder.

246
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

Exercícios

Questão 1. O desenvolvimento de aplicações móveis é uma área de crescimento contínuo na


indústria de tecnologia, com demandas crescentes por soluções funcionais, escaláveis e eficientes. Nesse
cenário, a tecnologia React Native se destaca. A respeito desse framework, analise as afirmativas.

I – O framework React Native é baseado na linguagem JavaScript e permite criar aplicativos móveis
renderizados nativamente para iOS e para Android.

II – O React Native foi feito com base no React, uma biblioteca JavaScript muito popular para a
construção de interfaces de usuário.

III – Não é possível integrar React Native ao ASP.NET Core.

É correto o que se afirma em:

A) I, apenas.

B) III, apenas.

C) I e II, apenas.

D) II e III, apenas.

E) I, II e III.

Resposta correta: alternativa C.

Análise das afirmativas

I – Afirmativa correta.

Justificativa: a tecnologia React Native permite que os desenvolvedores construam aplicações móveis
usando JavaScript e React. O que diferencia essa tecnologia de outras abordagens de desenvolvimento
móvel é sua capacidade de compilar aplicações para plataformas nativas, como iOS e Android, a partir
de uma base de código comum.

II – Afirmativa correta.

Justificativa: a tecnologia React Native permite que os desenvolvedores construam aplicações


móveis usando JavaScript e React. A biblioteca React é uma biblioteca JavaScript de código aberto,
desenvolvida pelo Facebook para a criação de interfaces de usuário em aplicações web.

247
Unidade IV

III – Afirmativa incorreta.

Justificativa: a integração entre ASP.NET Core e React Native é possível e pode ser poderosa para
o desenvolvimento de soluções móveis. Podemos criar um projeto ASP.NET Core para atuar como um
back-end de API e um projeto de React Native para atuar como interface do usuário. Essa combinação
permite que os desenvolvedores criem aplicações móveis completas, com um back-end sólido e uma
experiência de usuário imersiva.

Questão 2. A programação reativa é um paradigma que tem ganhado espaço dentro do


desenvolvimento ASP.NET Core. A respeito dela, analise as afirmativas.

I – Esse paradigma enfatiza a propagação de mudanças, permitindo que as aplicações reajam de


forma mais dinâmica e eficiente a eventos ou a alterações.

II – A programação reativa segue um padrão imperativo, com uma sequência linear de comandos.

III – No desenvolvimento ASP.NET Core, a programação reativa deve ser utilizada apenas em
aplicações de baixa concorrência e com volume reduzido de dados.

É correto o que se afirma em:

A) I, apenas.

B) III, apenas.

C) I e II, apenas.

D) II e III, apenas.

E) I, II e III.

Resposta correta: alternativa A.

Análise das afirmativas

I – Afirmativa correta.

Justificativa: a programação reativa é especialmente útil quando lidamos com eventos assíncronos,
como interações do usuário, chamadas de API, eventos de tempo e outros tipos de entrada e de saída de
dados. Ela visa criar sistemas mais eficientes, resilientes e responsivos.

248
DESENVOLVIMENTO DE SOFTWARE PARA INTERNET

II – Afirmativa incorreta.

Justificativa: a programação reativa é um paradigma de programação que se concentra em como


os sistemas reagem aos eventos e às mudanças de estado. Diferentemente da programação tradicional,
que segue uma abordagem imperativa e linear, a programação reativa baseia-se em fluxos de dados
assíncronos e reativos.

III – Afirmativa incorreta.

Justificativa: uma das principais vantagens da programação reativa no desenvolvimento ASP.NET


Core é a sua capacidade de lidar com cenários de alta concorrência e de grande volume de dados, sem
comprometer o desempenho da aplicação.

249
REFERÊNCIAS

ANDREWS, H. OAI – OpenAPI-Specification. GitHub, 2024. Disponível em:


https://github.com/OAI/OpenAPI-Specification. Acesso em: 24 maio 2024.

BLOCK, G. et al. Designing Evolvable Web APIs with ASP.NET: harnessing the power of the web.
Sebastopol: O’Reilly Media, 2014.

CARTILHA – acessibilidade na web. Fascículo 2: benefícios, legislação e diretrizes de acessibilidade na


web. São Paulo: Comitê Gestor da Internet no Brasil, 2015. Disponível em: https://tinyurl.com/mry8b4mj.
Acesso em: 24 maio 2024.

CUNNINGHAM, K. Accessibility Handbook: Making 508 compliant websites. Sebastopol:


O’Reilly Media, 2012.

DABIT, N. React Native in Action. Shelter Island: Manning, 2019.

DINCER, A.; BALKAN, U. Google Maps JavaScript Api Cookbook. Birmingham: Packt Publishing, 2013.

FIELDING, R. T. Architectural styles and the design of network-based software architectures. 2010.
Dissertação (doutorado) – Universidade da Califórnia, 2000. Disponível em: https://tinyurl.com/mr87j2bf.
Acesso em: 26 abr. 2024.

FREEMAN, A. Pro ASP.NET Core identity: under the hood with authentication and authorization in ASP.
NET Core 5 and 6 Applications. New York: Apress, 2021.

FREEMAN, A. Pro ASP.NET Core 7. Shelter Island: Manning, 2023.

GAMMELGAARD, C. Microservices in.Net Core: with examples in Nancy. Shelter Island: Manning, 2017.

HECK, J. Kubernetes for developers: use Kubernetes to develop, test, and deploy your applications with
the help of containers. Birmingham: Packt Publishing, 2018.

HIMSCHOOT, P. Programming Blazor: building web applications in .NET. New York: Apress, 2020.

HOFFMAN, K. Building microservices with ASP.NET Core: develop, test, and deploy cross-platform
services in the cloud. Sebastopol: O’Reilly Media, 2017.

HOLDENER, A. T. Ajax: the definitive guide. Sebastopol: O’Reilly Media, 2008.

HUNTER, K. Irresistible APIs: designin web APIs that developers will love. Shelter Island: Manning, 2016.

LAURET, A. The design of web APIs. Shelter Island: Manning, 2019.

250
LEBLANC, J. Programming social applications: building viral experiences with OpenSocial, OAuth,
OpenID, and Distributed Web Frameworks. Sunnyvale: Yahoo Press, 2011.

LINDLEY, C. DOM Enlightenment: exploring JavaScript and the modern DOM. Sebastopol:
O’Reilly Media, 2013.

LOCK, A. ASP.NET Core in action. Shelter Island: Manning, 2023.

MEYER, E. CSS: the definitive guide. Sebastopol: O’Reilly Media, 2006.

MORETO, S. et al. Bootstrap 4. Responsive web design. Birmingham: Packt Publishing, 2017.

PETERSON, C. Learning responsive web design: a beginner’s guide. Sebastopol:


O’Reilly Media, 2014.

ROTH, D. et al. Blazor for ASP.NET Web Forms developers. Redmont: Microsoft, 2023.

RUBY, S.; RICHARDSON, L.; AMUNDSEN, M. RESTful Web APIs: services for a changing world.
Sebastopol: O’Reilly Media, 2013.

SVENNERBERG, G. Beginning Google Maps API 3. New York: Apress, 2010.

251
252
Informações:
www.sepi.unip.br ou 0800 010 9000

Você também pode gostar