Razões para não usar web-services na comunicação do EJB com camada WEB

Correto, uma chamada rest seria uma operação completa(transação).

Mas quando vc quiser fazer duas operações que estão em URI diferentes em uma transação?. Cria outra operação que invoque as duas necessárias?.

E quando forem 3 ou, dependendo da situação 4, vai fazer uma URI para cada opção?

[quote=rock][quote=lsjunior] …
EJB locais vc terá um controle mais fino em transações, podendo colocar a transação em método do MB, por exemplo, podendo chamar vários EJB e fazer o commit junto.

[/quote]

utilizando da forma com REST eles precisarão ter uma URI que faça toda a transação necessária, correto?

Há algum problema nisso?[/quote]
Acho que a questão transacional não é algum limitante na discussão…se são EJBs, isso já deveria ser suficiente para os próprios favoráveis da adoção de arquitetura orientada à serviços estarem satisfeitos, pois expor EJB como serviço é um desenvolvimento bem simples.

Essa palestra é pertinente!

Felipe, o maior problema não seria expor os EJBs como serviço, mas sim fazer com que todos os métodos usados pela camada WEB (isso inclui desde inclusão, update, selects, chamadas ajax para autocomplete, por exemplo) sejam feitos via WS. O mais difícil, na minha opinião, seria consumir os Web Services…

[quote]Argumento tem bastante, mas se mesmo assim a empresa não aceitar daqui um tempo vc diz:

  • Falei que ia dar merda, rsrsrsrs[/quote]

kkkkkkkkkk

com certeza terei essa carta sempre na manga!!!

rock,

a idéia deles é fazer com que a comunicação entre MB e camada de negócio seja feita exclusivamente via WS (inclusive cadastros simples, métodos usados por chamadas ajax, desde um insert até um select para popular uma lista, etc.)

Continuando minha resposta anterior…

Imagine a interface

interface X { void fazA(); void fazB(); }

E no seu MB

class MB { X x; // A interface void fazA() { x.fazA(); } void fazB() { x.fazB(); } }

Ai seu cliente pede para que em determinados momentos A e B sejam feitas juntas, porém cada operação ainda poderá ser feita separada. Além disso pediu para adicionar a operação C que também poderá ser feita junto de A e B.

O correto com EJB seria isso:

class MB { X x; ... @TransationalAttribue... void fazAB() { x.fazA(); x.fazB(); // Se der erro em B o container da rollback em A também } ... @TransationalAttribue... void fazABC() { x.fazA(); x.fazB(); // Se der erro em B o container da rollback em A também x.fazC(); // Se der erro em C o container da rollback em A e C também } }

Agora imagine isso com WS, vc teria que criar um método para cada operação completa:

interface XWS { // Aqui para o WS expor os métodos que fazem várias coisas void fazA(); void fazB(); void fazC(); void fazAB(); void fazABC(); }

E no seu MB

class MB { X x void fazAB() { x.fazAB(); } void fazABC() { x.fazABC(); } }

Então acaba precisando fazer algums métodos específicos apenas para o WS. Olha a bagunça que fica para poder reaproveitar o código.

[quote=lsjunior]Correto, uma chamada rest seria uma operação completa(transação).

Mas quando vc quiser fazer duas operações que estão em URI diferentes em uma transação?. Cria outra operação que invoque as duas necessárias?.

E quando forem 3 ou, dependendo da situação 4, vai fazer uma URI para cada opção?[/quote]

Sim. Seria um serviço composto por outros serviços.
Veja a observação entre parênteses no link que postei antes:

[quote=http://blog.xebia.com/2008/05/12/top-10-soa-pitfal…rrect-granularity-of-services/]…
And lastly, the service should be as autonomous as possible. If someone want to use a service he should not be forced to use other services also (note that the implementation of the service may use other services).
…[/quote]

É importante lembrar que deve haver uma cultura na equipe de verificar a documentação na hora de criar um novo serviço para que ocorra o reuso desejado.
A API poderia ser colocada em uma wiki talvez.

Esse não é um bom exemplo, pois estudando a granularidade das transações, ele teria que expor um método único, com cara de Facade, e não N métodos com granularidades menores e outros N que encapsulem um Business Process chamando os métodos com granularidades menores.

Agora o negócio se torna mais complexo pois terá que existir governança dos serviços…daqui a pouco estaremos falando de ESB, quer apostar?

[quote=lsjunior]Continuando minha resposta anterior…

Imagine a interface

interface X { void fazA(); void fazB(); }

E no seu MB

class MB { X x; // A interface void fazA() { x.fazA(); } void fazB() { x.fazB(); } }

Ai seu cliente pede para que em determinados momentos A e B sejam feitas juntas, porém cada operação ainda poderá ser feita separada. Além disso pediu para adicionar a operação C que também poderá ser feita junto de A e B.

O correto com EJB seria isso:

class MB { X x; ... @TransationalAttribue... void fazAB() { x.fazA(); x.fazB(); // Se der erro em B o container da rollback em A também } ... @TransationalAttribue... void fazABC() { x.fazA(); x.fazB(); // Se der erro em B o container da rollback em A também x.fazC(); // Se der erro em C o container da rollback em A e C também } }
[/quote]
Acho que deveria ser feito no EJB em um novo método. Por que? para centralizar os processos de negócio a+b ou a+b+c.
Se for necessário em outro lugar (outro MB), estará pronto no EJB para ser utilizado.

Vc também precisou criar o fazAB e o fazABC, só que criou no ManagedBean…

[quote]Acho que deveria ser feito no EJB em um novo método. Por que? para centralizar os processos de negócio a+b ou a+b+c.
Se for necessário em outro lugar (outro MB), estará pronto no EJB para ser utilizado. [/quote]

Claro que não, só vai duplicar as regras de negócio. Se vc tem um método que grava um usuário e outro que grava o grupo, em determinado momento vc quer gravar ambos, tem lógica duplicar os métodos sendo que eles já funcionam corretamente?. Vc apenas tem que garantir que ambos serão executados corretamente ou tudo deve ser desfeito. Outra coisa é que quem sabe quando invocar esse métodos é o cliente, no caso o MB. Se O MB desejar gravar 10 usuários, modificar 3 grupos, alterar mais 5 usuários, remover 1 usuário e depois modificar criar alguns grupos tudo na mesma transação é ele que sabe o que faz, o EJB fará a parte dele(validar as regras negociais de cara operação, inserir os dados no banco, gravar log, etc).

Isso fiz nele por que a tela precisa salvar os dados juntos, mas o EBJ continua com os métodos separados. A reutilização dos EJBs é bem maior visto que não vou precisar criar um método para cada situação que o cliente precisar.

Será que não vai aparecer UM maluco aqui para defender que devem usar Webservices? ? ? ? Hum… será porque essa é uma idéia totalmente sem sentido?!?!?! haha

Ou então o pessoal da empresa do felipe_gdr está em um nível de genialidade muito além, que nós pobres programadores não conseguimos compreender.

Consigo imaginar o que aconteceu: essa idéia provavelmente saiu do cara que fala mais bonito, aquele que faz um discurso com bastante convicção e os gerentes ficam pagando o maior pau. Então, acertei? :slight_smile: Bom… a má notícia é que nenhum tipo de argumento lógico vai mudar essa decisão. Pense com carinho na estratégia do “eu avisei”. Guarde provas.

Alguns dos argumentos são esses:

1 - caso seja necessário rodar a camada web em um servidor diferente da camada de negócio/EJB, já estaria toda a arquitetura pronta (a meu ver, isso é bem improvável, é mais lógico manter as camadas “locais” e clusterizar vários servidores do que separá-las. Aliás já temos esse cenário do aplicativo rodar em cluster em alguns clientes)
2 - caso um dia seja preciso disponibilizar todas as funções to aplicativo para mobile, já estaria tudo pronto também (muito, mas MUITO, improvável. O sistema é super complexo, mais de 3000 tabelas, milhares de funções. Via celular só consigo imaginar funções de consulta ou ações bem pontuais.)
3 - deixar a aplicação mais moderna (ao meu ver, uma aplicação moderna é aquela que utiliza as tecnologias com sensatez e análise aprofundada, escolhendo a melhor solução para cada caso específico. Simplesmente usar WS não significa que a aplicação é moderna).

Enfim, o outro lado da discussão quer se preparar para cenários que são, no mínimo, improváveis, mas são os desenvolvedores mais experientes da equipe. Eu cheguei há pouco tempo, então tenho que provar por A mais B que o melhor caminho é usarmos WS sim, porém com moderação.[/quote]

Só para não dizerem que não tentamos, alguns comentários sobre cada ponto:
1- Na pior das hipóteses, se realmente houver essa possibilidade, a solução mais natual é usar EJB remoto baseado em RMI. A performance é bem melhor pois a serialização acontece em um nível mais baixo sem a gordura do HTTP. O desenvolvimento é quase tão rápido como os EJBs locais pois a comunicação é transparente. E evidentemente os dois lados serão feitos em Java, o que elimina questões de compatibilidade entre plataformas.
2- Exatamente o que você disse - por que sacrificar o sistema inteiro se UM DIA - TALVEZ - QUEM SABE - ACHO QUE NÃO uma ou duas consultas serão implementadas no mobile? E se realmente der a louca de replicar o sistema inteiro, estão achando que criar interfaces com @WebService para os EJBs vai fazer alguma diferença no volume de trabalho? Pobre ilusão!
3 - Quer coisa mais moderna que injeção automática com @EJB ? Sabe quantos anos o Java EE teve que evoluir até chegar nessa feature? Ora pois…

[quote=lsjunior][quote]Acho que deveria ser feito no EJB em um novo método. Por que? para centralizar os processos de negócio a+b ou a+b+c.
Se for necessário em outro lugar (outro MB), estará pronto no EJB para ser utilizado. [/quote]

Claro que não, só vai duplicar as regras de negócio. Se vc tem um método que grava um usuário e outro que grava o grupo, em determinado momento vc quer gravar ambos, tem lógica duplicar os métodos sendo que eles já funcionam corretamente?. Vc apenas tem que garantir que ambos serão executados corretamente ou tudo deve ser desfeito. Outra coisa é que quem sabe quando invocar esse métodos é o cliente, no caso o MB. Se O MB desejar gravar 10 usuários, modificar 3 grupos, alterar mais 5 usuários, remover 1 usuário e depois modificar criar alguns grupos tudo na mesma transação é ele que sabe o que faz, o EJB fará a parte dele(validar as regras negociais de cara operação, inserir os dados no banco, gravar log, etc).

Isso fiz nele por que a tela precisa salvar os dados juntos, mas o EBJ continua com os métodos separados. A reutilização dos EJBs é bem maior visto que não vou precisar criar um método para cada situação que o cliente precisar.[/quote]

Opa, acho que vc não entendeu o que eu quis dizer nos posts anteriores.

Continuando seu exemplo fazA, fazB, fazAB digamos que sejam respectivamente:
cadastraCliente(Cliente cliente), cadastraProduto(Produto produto), cadastraPedido(ClienteProduto cp)

Então o cadastraPedido além de realizar as outras operações, faz mais alguma coisa. É um serviço de negócio composto por outros (ele poderia também cadastrar o cliente e o produto se já não estiverem cadastrados)
Nesse sentido eu não criaria no MB.

Agora se o seu fazAB (com transações individuais) é somente chamar os outros 2 (cadastraCliente e cadastraProduto), seria melhor fazer chamadas assíncronas. Não criaria ‘cadastraClienteProduto’ como serviço.

Se necessitar que fazAB execute na mesma transação porque não adianta gravar só Cliente ou somente Produto, talvez seja porque este fazAB (com transação sobre tudo) deveria ser um serviço (cadastraPedido).

Obs.: isso é minha opinião, posso estar completamente errado, mas é o que faz sentido para mim por enquanto

IMHO, é um p*** tiro no pé fazer toda a comunicação interna da aplicação via Web Services. Porém, isso tem mais cara de que é pra garantir que os serviços estão funcionando do que pela aplicação em sí… nesse caso, valeria a pena usar os EJB’s, e ao mesmo tempo expô-los como web services (usando aí uma boa dose TDD para garantir a funcionalidade dos web services).

(A não ser que a aplicação seja usada numa empresa que aplica bem SOA. Nesse caso, seria melhor expor mesmo algumas - senão todas - as funcionalidades como web services, para ter certeza absoluta de que outros front-ends e aplicações podem utilizar os serviços).

[]'s

Sinceramente, acho um incrível amadorismo essa opção do WS dentro do próprio servidor… pior ainda… um servidor JEE… e pior ainda… restful de java pra java (quem já fez cliente restful em java sabe)… e pior ainda… pra usar com JSF.
JSF é bom, mas se for fazer um managedbean chamar um serviço restful, então faz as chamadas direto do cliente (com jquery p/ exemplo), mas fazer toda a app em javascript… bom… aí é outra discussão.
E a referência cíclica das entidades vão ser uma dor de cabeça pra vcs com certeza… Sei q com o Apache CXF, tem como resolver, mas com gambiarra… então não vão fugir de DTOs + Assemblers.

E se é por utilizar JSON… que ilusão em ganhar performance… principalmente em grandes quantidades de dados.

Quanto a mobilidade, é óbvio que se deve expor somente os serviços que vão ser usados.

Cara… se a tua opinião não for ouvida… paciência… ao menos tu vai dormir tranquilo, que tu fez tua parte.

[quote=felipe_gdr]Amigos gujeiros,

estou no meio de uma discussão acirrada com minha equipe de desenvolvimento em relação ao uso de Web Services em nossa nova versão do aplicativo web.

Nosso aplicativo irá usar EJB 3 e JSF, logo teremos um EAR e um WAR, a princípio rodando dentro do mesmo JBOSS (ou Websphere).

Os defensores do Web Service são a favor de que a comunicação entre EJB e Web seja inteiramente feita através de Web Services. Eu faço parte do outro lado da discussão, e sou a favor de expormos via Web Services só os métodos que deverão ser chamados por aplicativos terceiros (mobile, por exemplo).

Na minha opinião, a utilização indiscriminada de Web Services iria adicionar mais uma camada de complexidade, sem contar o tráfego de arquivos XML, ou JSON. Principalmente porque nosso aplicativo usa MUITO ajax, partial form submission, autocomplete. Meus argumentos, no entanto, não foram fortes suficientes.

Gostaria de mostrar alguma prova concreta, artigo ou argumento irrefutável de que a decisão deles está totalmente equivocada.

Vocês concordam comigo?

Abraços!!![/quote]
Insanidade isso, ja passei por uma discussao tambem em defesa de nao usar webservice sem necessidade, mas foi na epoca do “boom” do SOA, ficava ouvindo “tudo vai ser webservice”. Mas hoje é bizarro alguem ainda decidir usar sem necessidade REAL, coisa de quem tem prazer com a complexidade.

Sobre falar “eu sei que ia dar m”, dar m nao vai, só vao ter que ralar mais, aumentar o custo do projeto e os clientes vao sofrer um pouco ate a coisa funcionar bem.