Services no Angular e por que você deveria se importar com eles?
- #TypeScript
- #Angular
No mundo do desenvolvimento Angular, os services desempenham um papel crucial na criação de uma arquitetura robusta e modular para suas aplicações. Eles permitem a separação de preocupações, reutilização de código e gerenciamento eficiente de estado. Esse post pretende apresentar o conceito de services no Angular, entender por que eles são tão importantes, como determinar quando deveríamos usá-los e ilustrar sua utilidade através de exemplos práticos, como serviços de autorização, carrinho de compras e configurações personalizadas.
O que são os Services do Angular afinal?
Services no Angular são classes que fornecem funcionalidades específicas que podem ser compartilhadas em toda a aplicação. Eles são usados para separar a lógica de negócios, manipulação de dados e outros aspectos do código que não pertencem diretamente aos componentes. Isso promove uma arquitetura modular, facilitando a manutenção, reutilização e testabilidade do código.
Sua aplicação usa autenticação, por exemplo, assim todos os módulos precisam verificar se o usuário está autorizado a usá-los. Uma alternativa seria implementar toda lógica de login e verificação de credenciais em cada um dos módulos em que o usuário precisasse estar logado para garantir a segurança, outra seria usar um Serviço para login/autorização que realizaria essa tarefa e quando algum outro módulo quisesse saber se o usuário está logado ou não bastaria injetar o serviço e consultá-lo.
Por que eu deveria usá-los?
Separação de Preocupações: Services permitem separar a lógica de negócios da apresentação, garantindo que seus componentes se concentrem na interação com o usuário, enquanto a lógica mais complexa é tratada em services.
Reutilização de Código: Ao colocar funcionalidades compartilhadas em services, você pode reutilizá-las em diferentes partes da aplicação, evitando duplicação de código. Além disso, se a estrutura da API ou as URLs mudarem, você só precisará fazer as alterações no Service, mantendo os componentes desacoplados e sem a necessidade de modificá-los.
Testabilidade: Services podem ser facilmente testados isoladamente, o que ajuda a garantir a qualidade do código e a detecção precoce de bugs.
Gerenciamento de Estado: Services podem ser usados para gerenciar o estado da aplicação, permitindo uma comunicação eficiente entre diferentes componentes.
Ok, mas como saber se você precisa de um Service?
Responda as seguintes pergutas:
- Você tem lógica que não está diretamente relacionada à apresentação?
- Você deseja compartilhar dados ou funcionalidades entre vários componentes ou módulos?
- Você está trabalhando com chamadas HTTP recorrentes, manipulação de dados ou autenticação?
- Você quer uma forma organizada de gerenciar o estado global da aplicação?
Na prática, quando você percebe que está repetindo as mesmas requisições para obter os mesmos dados ou então quando a origem da informação está demasiadamente distante da apresentação/ utilização dos dados são sinais expressivos que a lógica da aplicação pode ser melhorada.
Os apps feitos com React apresentavam esse cenário cômico e trágico onde as propriedades cruzavam diversos componentes até chegarem no último que deveria exibi-las na tela, enfim se você tiver alguma propriedade passando por um componente, que não a utiliza, apenas para chegar em um componente filho, já sabe: você poderia criar um Serviço.
Como era no React:
Componente A (atualiza prop) -> Componente B (prop) -> Component C (prop) -> Componente D (mostra prop)
Como pode ser no Angular:
Componente A (injeta serviço, atualiza prop) -> Componente B -> Component C -> Componente D (injeta o serviço, pega prop, mostra prop)
Alguns cenários comuns onde utilizamos Serviços:
1. Service de Autorização:
Um serviço de autorização é responsável por gerenciar o acesso e as permissões dos usuários na aplicação. Ele pode verificar se um usuário tem as credenciais necessárias para acessar determinadas partes da aplicação.
typescript
// authService.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
isAuthenticated = false;
login() {
// Lógica de autenticação
this.isAuthenticated = true;
}
logout() {
// Lógica de saída
this.isAuthenticated = false;
}
}
2. Service de Carrinho de Compras:
Um service de carrinho de compras gerencia os itens que um usuário deseja comprar, permitindo adicionar, remover e calcular o total.
typescript
// cartService.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CartService {
items: any[] = [];
addToCart(item: any) {
this.items.push(item);
}
removeFromCart(item: any) {
// Lógica para remover item do carrinho
}
getTotal() {
// Lógica para calcular o total
}
}
3. Service de Configurações Personalizadas:
Um service de configurações personalizadas permite que os usuários ajustem as preferências da aplicação, como temas, idiomas e outras configurações.
typescript
// configService.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
theme: string = 'light';
language: string = 'en';
updateTheme(newTheme: string) {
this.theme = newTheme;
}
updateLanguage(newLanguage: string) {
this.language = newLanguage;
}
}
Suponha que você tenha uma classe chamada "Profile" para exibir os dados do usuário e ele consiga fazer algumas escolhas referentes aos temas ou idioma de sua preferência. Poderíamos usar o serviço "ConfigService", do exemplo acima, para atualizar essas configurações com um código semelhante ao código abaixo:
typescript
// profile.model.ts
import { ConfigService } from './config.service';
export class Profile {
constructor(private configService: ConfigService) {}
updateProfileSettings(newTheme: string, newLanguage: string) {
this.configService.updateTheme(newTheme);
this.configService.updateLanguage(newLanguage);
}
}
Nesse exemplo, a classe "Profile" usa o serviço "ConfigService" para atualizar as configurações de tema e idioma, mantendo uma separação clara entre as preocupações de gerenciamento de perfil e configurações.
Esse seria o exemplo mais comum de utilização do serviço, importamos o arquivo que contém a classe do Service. Declaramos o serviço no método __construtor e a partir daí já podemos utilizá-lo na classe.
* Lembre-se: Toda a alteração de estado que o serviço sofrer será refletida para toda a aplicação, pois o service é o mesmo. Isto significa que o theme que escolhermos na classe "Profile" será o mesmo para todos os componentes que também injetarem o serviço "ConfigService". A não ser que você use um provedor de serviços (provider factory) que é usado para criar instâncias personalizadas de serviços, mas isso é assunto para outro dia.
** Os exemplos são ilustrativos e não têm suas funcionalidades implementadas.
Conclusão
Os services desempenham um papel fundamental no desenvolvimento Angular, permitindo uma arquitetura modular e robusta. Eles promovem a reutilização de código, separação de preocupações e facilitam a manutenção. Nos exemplos de serviço de autorização, carrinho de compras e configurações personalizadas, vimos como os services podem ser aplicados de maneira prática para melhorar a estrutura e a funcionalidade de uma aplicação Angular. Portanto, da próxima vez que você estiver desenvolvendo uma aplicação, lembre-se de considerar o uso de services para tornar seu código mais organizado e escalável.
Por hoje é só pessoal, espero que tenha sido claro o suficiente para inspirar você. Qualquer dúvida ou sugestão, comente, estou a disposição. Fez um projeto legal? Compartilhe. Até a próxima.