Vue.js: injetando serviços em componentes de forma transparente

Vue.js: injetando serviços em componentes de forma transparente

Você provavelmente já viu alguns exemplos de aplicações utilizando Vue e já deve ter percebido que (atualmente em meados de 2018) ele ainda passa por uma fase de fragmentação quanto ao uso da ferramenta onde vários grupos tem várias arquiteturas sendo aplicadas e testadas.

Esta situação é um pouco desconfortável para alguns, mas ela espelha um momento cada vez mais comum no desenvolvimento web: POSSIBILIDADES.

É muito provável que se você perguntar a cada arquiteto de cada estrutura visitada ele tenha partido de alguma experiência anterior pela qual passou e tenha organizado sua estrutura porque a que vinha usando o deixou na mão ou não escalou nesta ou naquela situação. Conosco não é muito diferente. Nosso caso era realmente a preocupação com a flexibilidade e rapidez. Precisávamos de estruturas que fossem criadas rapidamente e que fossem simples de serem atualizadas, sem ter que abrir centenas de arquivos para aplicar mudanças; esse era nosso desafio.

Disclaimer: o conteúdo do artigo são apenas sugestões de coisas que usamos no nosso dia-a-dia, fique à vontade para concordar e/ou discordar, aproveitando as experiências da forma que melhor lhe convir.

Serviços

Nos contextos de arquitetura de software o termo serviço refere-se a uma funcionalidade ou um conjunto de funcionalidades de software com um propósito que pode ser reutilizado em diferentes ocasiões. Geralmente associamos os acessos à recursos HTTP ao nome Service, mas nem sempre usamos uma estrutura dedicada à isso para cada domínio da nossa aplicação, o que, particularmente se tornou um problema.

Devemos ter cuidado ao usar recursos como this.$http.get('/api/v1/products') dentro da nossa aplicação, pois estamos pulverizando uma camada lógica importante por toda a aplicação.

Vou deixar um link abaixo como referência para construções de serviços, caso queira se aprofundar um pouco mais sobre o tema (e ainda não conheça): Vue.js: Trabalhando com Serviços Serviços são parte fundamental em aplicações elaboradas, não importa o ambiente. Veja como trabalhar com eles no Vue.jsblog.codecasts.com.br

Mantendo Contratos

Para quem está acostumado com linguagens onde a Orientação a Objeto possui suporte à recursos como interfaces, métodos abstratos, enum, entre outros, o javascript se torna um pouco assustador por não entregar esse tipo de composição. Contudo, isso não é exatamente um problema quando você organiza a sua aplicação porque essa chamada falta de rigidez pode ser compensada de outras formas para forçar que alguns caminhos não sejam seguidos. Vou deixar o link abaixo com algumas dicas de composição de serviços: Vue.js Brasil - Artigos em Português sobre Vue.js Artigos em Português sobre Vue.jsvuejs-brasil.com.br

Criando Serviços Extensíveis

Para poder seguir com este material apresentaremos uma solução simples para criar um Service que pode ser estendido e usado nos domínios das entidades com as quais estão lidando. A seguir será apresentada uma lista de documentos e a respectiva explicação sobre o que representa cada um deles.

A estrutura

src/main.js

Um pequeno exemplo de uso de como o serviço será usado. Ele importa o service de Product e constrói uma instância para poder executar o método read e imprimir a saída;

src/domains/Product/Service/Product.js

A especialização do serviço Api para ser usado no escopo da entidade Product;

src/service/Api.js

Serviço para consumo de API’s que entrega 4 métodos básicos para realizar o que é costumeiramente chamado de CRUD;

src/service/Service.js

Contrato básico para a factory de instâncias do Service;

src/service/helper.js

Apenas uma função fake para simular o delay da troca de contexto de da manipulação dos dados.

A saída exibida nesse caso é algo parecida com a imagem abaixo.

Com o que fora apresentado até aqui não é difícil perceber que podemos usar essa estrutura para representar diversas estratégias de API’s porque não está fechado o que o nosso serviço consome. Essa deve ser a visão do componente acerca do service: conhecer o contrato e não a implementação.

Embora o Javascript não tenha estruturas “formais” para contratos, é possível criar padrões para que a codificação componha esses contratos de forma orgânica

Se quiser se aprofundar em abordagens de gestão de services pode dar uma olhada nessa dica de artigo (que recebi do Vinicius Reis) onde é explorado a níveis bem profundos o uso do serviço como um modelo da entidade totalmente isolado da apresentação do componente. How not to suffer with APIs Rethinking Apicase and why I still never used axiositnext.io

Lidando com Componentes

Bom, se o serviço agora é uma estrutura totalmente segmentada do meu componente, como posso fazer uso desse recurso dentro do componente? A resposta dessa pergunta também é uma pergunta: quão flexível será seu componente e quão dinâmica será sua estrutura?

Importando serviços para o meu componente

Essa estratégia é bem simples e consiste basicamente em usar os módulos javascript para usar o service dentro do escopo do seu componente.

Se precisar de uma estratégia mais eficiente de distribuir o service, pode usar um plugin para manipular o estado dele dentro do componente. Seguindo essa abordagem teríamos o ProductTable.vue:

E teríamos uma modificação no protótipo do Vue através do src/service/Plugin.js:

Com esta segunda abordagem, mesmo que algum desenvolvedor sem querer faça algo como this.$service = null, a resposta do Vue será contundente:

Com a implementação do plugin feita dessa forma o service é passado para o componente e o então ele “descobre” se este é um item das opções do construtor da instância do Vue ou se é uma prop do componente, entregando um elemento, que como vimos acima, é imutável; o que nos leva a próxima abordagem: passar os serviços via props.

Utilizando serviços como props

No ecossistema do Vue (na verdade é um conceito um pouco mais abrangente que isso) uma prop é um estado que é passado para um componente. Se não estiver recordando muito bem como funcionam essas propriedades dos componentes recomendo fazer uma visita no link abaixo antes de continuar. Props - Vue.js This page assumes you've already read the Components Basics. Read that first if you are new to components. HTML…vuejs.org

Com a leitura em dia será fácil compreender que usando props tenho a capacidade de passar parâmetros para meus componentes sem ter que deliberadamente deixar esse parâmetro “hard-coded” dentro dele.

Para receber uma prop dentro de um componente é preciso declarar essa necessidade. O resultado é semelhante ao exemplo a seguir:

O que implicaria em um caso de uso semelhante à <ProductTable v-bind:service="service"/>.

Embora essa abordagem não seja ruim, ela possui alguns pontos que devem ser observados. Entre as situações que não me deixam confortável temos a questão de usar um estado do componente (uma propriedade no data) para abrigar o serviço que será mapeado à prop, e a necessidade imperativa de ter que criar um arquivo .vue para cada rota implementada.

Usando o Router para injetar dependência

Durante a construção de app’s mais robustos geralmente usamos um router. O Vue Router é uma ferramenta que faz parte do ecossistema do Vue e nos permite criar rotas para nossos componentes. Ele tem suporte à informar as props que serão usadas para montar o componente e isto é descrito no trecho abaixo da documentação. [Passing Props to Route Components · vue-router const User = { props: ['id'], template: ' User {{ id }} ' } const router = new VueRouter({ routes: [ { path…router.vuejs.org](https://router.vuejs.org/en/essentials/passing-props.html)

No caso do nosso exemplo, vamos explorar o function mode onde as props serão geradas por uma função que recebe a rota carregada como parâmetro. Com o service sendo uma prop poderemos passá-lo por parâmetro através da rota onde seu componente será montado.

Como podemos ver no exemplo abaixo, será possível combinar as duas abordagens no seu projeto. Poderemos usar um mesmo componente recebendo o service por props ou através de $options, template, render ou route porque o acesso ao $service será transparente para o componente.

Conclusão

O Vue é muito flexível e deixa à cargo da sua capacidade de manipulação do Javascript a criação do ecossistema em que o componente está inserido. Tenha sempre cuidado para escolher abordagens que te permitam escalar a sua aplicação de forma mais objetiva possível pesquisando e estudando o máximo que puder antes de começar a escrever seus códigos. Ademais, você pode começar a fazer uso dessas metodologias para fazer seus requests sem que seu componente perceba que algo mudou.

Isolar o comportamento dos serviços é uma boa pedida em tempos onde estão surgindo opções interessantes para manipulação de dados, como o GraphQL.

Fique à vontade para enviar suas dúvidas, sugestões e/ou elogios. Para falar mais sobre **VueJS fique ligado na comunidade e em todo o seu ecossistema : ) [Vue.js Brasil - Artigos em Português sobre Vue.js** Artigos em Português sobre Vue.jsvuejs-brasil.com.br](http://vuejs-brasil.com.br) vuejs-br/comunidades comunidades - Comunidades Vue.js ao redor do Brasilgithub.com

Ah, já ia esquecendo, segue o link do repositório e fica a dica para seguir os commits que será possível ver a evolução da mesma forma que a estrutura foi evoluindo nos artigos. wilcorrea/transparent-services Contribute to transparent-services development by creating an account on GitHub.github.com