Como falado no último post, O reúso é muito importante, mas não pode ser encarado como único direcionador na hora de levantar ou classificar um serviço. Tá, mas o que isso tem a ver com Granularidade de Serviços?
Senti a necessidade de escrever sobre Como o Reuso pode Atrapalhar uma iniciativa SOA! Estranho né? Mas foi algo que eu percebi que pode acontecer e precisava de uma certa atenção. Mas antes disso é importante explicar definir alguns conceitos, o primeiro deles é a Granularidade de Serviço.
Definição
Segundo Thomas Erl, granularidade de serviços é:
The granularity of the service’s functional scope, as determined by its functional context, is simply referred to as service granularity. A service’s overall granularity does not reflect the amount of logic it currently encapsulates but instead the quantity of potential logic it could encapsulate, based on its context. A coarse-grained service, for example, would have a broad functional context, regardless of whether it initially expresses one or ten capabilities. – SOA Principles of Service Design
Logo, quando alguém usa o termo Granularidade de Serviço, devem estar se referindo a quantidade de escopo/lógica de um serviço, mesmo que esta relação (escopo vs quantidade de lógica) não seja um pra um. Ou seja, um serviço de granularidade grossa (coarse-grained) fará muita ‘coisa’, enquanto um serviço de granularidade fina (fine-grained) fará pouca ‘coisa’.
Para ficar mais simples de entender e memorizar, associe o granularidade fina com areia (grãos muito pequenos), e granularidade grossa com pedras (grãos bem maiores).
Granularidade Grossa vs Granularidade Fina
Poderia parar por aqui, mas é importante contextualizar este termo na modelagem de serviço, e mostrar como seu (mau) uso pode influenciar a implantação de uma arquitetura orientada a serviços na sua empresa.
Para isso vamos recorrer a uma famosa analogia de SOA, a que compara serviços a peças de lego. Ela é bastante utilizada pois ambos podem ser combinados e re-combinados (mash-ups) para criar outras formas (funcionalidades).
Neste contexto, um serviço de granularidade grossa seria uma daquelas peças de Lego Duplo, aqueles para crianças menores que possuem blocos 4 vezes maioes que as tradicionais.
Por outro lado, um serviço de granularidade fina seria uma daquelas menores peças, de 1×1.
Ambas são importantes, as primeiras para diminuir a complexidade e aumentar a velocidade da construção de uma peça grande, e as últimas para possibilitar os detalhes.
Muito complicado? Espera que tem mais coisa, o Thomas Erl definiu quatro tipos de granularidade:
Tipos de Granularidade
Serviço
Como comentei acima, escopo e quantidade de lógica não são um pra um. A Granularidade de Serviço está ligada ao pontencial de lógica que o serviço pode encapsular, em seu contexto.
Um serviço Endereço
possui uma Granularidade mais grossa que o EnderecoEntregaCliente
por exemplo. Independentemente do número de operação de cada um. O escopo do serviço Endereço
pode abrangir desde uma busca de CEP até a manutenção de endereço de entrega de um cliente.
Capacidade
Esta granularidade representa o escopo funcional de uma determinada operação. Está mais ligada a quantidade de lógica presente em uma operação.
Dados
A Granularidade de Dados está ligada à quantidade de dados trafegados pela operação. representa o escopo funcional de uma determinada operação. Está mais ligada a quantidade de lógica presente em uma operação.
Validação
A Granularidade de Validação representa o nível de restrições dos parâmetros de entrada de uma operação, considerando tipos, obrigatoriedade, valores permitidos, etc. Uma operação que recebe um xsd:anyType
possui uma granularidade muito grossa, enquanto uma operação que recebe elementos com tipos muito bem definidos, com restrição de obrigatoriedade e range de valores definidos, possui uma granularidade muito fina.
Conclusão
Apesar dos detalhes comentados acima este assunto é pouco explorado no dia-a-dia. Na grande maioria dos casos, o que se entende por granularidade é uma mistura dos dois primeiros tipo apresentados (Serviço e Capacidade), o que pode gerar confusão pois a primeira está ligada ao serviço e a ultima a operação.
Agora sendo mais prático, qual nível granularidade devo usar? A resposta para esta pergunta leva vários fatores em consideração. Por via de regra o ideal seria um mix:
- Poucos serviços com Granulariade Grossa, que teriam pouco ou nenhum reúso, mas abstraem um processo de negócio de granularidade média;
- Se houverem apenas serviços neste nível, não haveria nenhum reúso, gerando duplicação de código nos provedores;
- Muitos serviços com Granulariade Média, que teriam potencial de reúso (mas cuidado com esta característica, ela não deve ser a única envolvida na decisão). Normalmente representam uma operação completa;
- Alguns serviços com Granularidade Fina, normalmente serviços de validação, técnicos, que apoiariam os de Granularidade Média na composição dos serviços de Granularidade Grossa;
- Se hoverem apenas serviços neste nível, haverá muito reúso, porém pouco valor em cada reúso, pois cada serviços realiza muito pouca lógica. Os consumidores terão que (re) implementar a composição de serviços constantemente (duplicação de código nos consumidores). A abstração será afetada, pois eventualmente os consumidores terão que conhecer mais dos sistemas para fazer;
Logo, o segredo está no equilíbrio 😉
Faz sentido?
Sim! Muito sentido! O equilíbrio é a alma para a definição da granularidade de serviços da corporação.
Ser xiita com a granularidade levada ao menor grau pode ser prejudicial ao negócio; muitos que não precisariam de uma granularidade baixa acabarão “morrendo” com o tempo.
Pensando aqui… Hoje, com o conceito de microserviços é possível que esta confusão tenha aumentado, pois, este conceito difundido de forma indevida, pode ocasionar uma granularidade extremamente fina. O que acha?
Quando falamos em Microserviços, estamos utilizando o padrão arquitetural REST. Neste contexto a forma de pensar na modelagem muda completamente.
Inicialmente o estilo sugere uma granularidade relativamente fina, ao ‘impor’ a Uniform Interface a maioria dos Recursos seriam CRUDs. Porém é possível modelar o Recurso
/clientes
onde o verboPOST
iniciaria um processo de negócio assíncrono (BPEL) de credenciamento de clientes. Neste exemplo a granularidade deste verbo seria grossa.Mas isso seria assunto para outro blogpost 😉