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

56 respostas
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!!!

56 Respostas

L

Concordo com vc.

Não tem o menor sentido usar Web Services para a comunicação interna das camadas de sua aplicação. Apesar da inteface e o uso ser semelhante com EJB/Web Services, o custo para transformar as entidades em XML/JSON será considerável.

Além do mais que não são todos os métodos necessários para o JSF que poderão ser disponibilizados via serviço. Métodos de autenticação, por exemplo, a meu ver não podem ser expostos como serviço, visto que qualquer desenvolvedor pode fazer um robo para forçar a autenticação apenas com o WSDL e o endereço do serviço. Falando nisso vc teria que adicionar uma camada de segurança para restringir o acesso aos serviços, seja por autenticação(usuário/senha, certificado, etc), restrição de endereço IP, etc, isso também adiciona mais custo para aplicação.

Normalmente crio uma camada de Web Service acima da camada EJB apenas com os métodos e entidades que serão expostas, isso facilita tratar relacionamentos ciclícos, campos lazy, etc.

Tem muitos pontos negativos em fazer o sistema todo usando serviço, ainda mais quando não é um sistema distribuído.

Jair_Rillo_Junior

Quando você diz Web Services, significa usar o protocolo SOAP? Se sim, realmente a complexidade é um pouco maior. No caso de trabalhar diretamente com REST, a específicação e os frameworks estão bem legais e ajuda bastante na conversão dos dados de xml/json para java e etc.

Porém eu também sou a favor de expor apenas o que é necessário para o mundo “externo”. Eu mesmo trabalho em uma aplicação assim.

Um pouco que talvez você possa argumentar é em relação a performance. A comunicação local, através de RMI será muito melhor que a comunicação através de HTTP (Web Services).

Espero ter ajudado

felipe_gdr

Jair, obrigado pela resposta.

Ainda não está decidido se usaríamos SOAP ou REST, provavelmente REST…

No nosso caso, não precisaríamos nem usar o RMI para a comunicação entre EJB e camada Web, pois os dois projetos estariam no mesmo JBOSS.

Dentro do Managed Bean quando coloco a anotação @EJB o bean já é injetado e invoco os métodos de maneira transparente. É realmente muito fácil e rápido de programar, e é essa facilidade que eu não queria comprometer, usando Web Service.

felipe_gdr

lsjunior,

não havia pensado nessa questão da segurança e autenticação. Realmente a complexidade irá ficar maior ainda.

Desculpe a pergunta, mas o que você quer dizer com a frase abaixo?

Abraços!

A

Uma dúvida: quais são os argumentos “deles” para usar web-service em tudo?

L

Quando uma entidade E1 é relacionada com a E2, a E2 com a E3 e a E3 volta para a E1. Então tem um relacionamento circular que nunca acaba, que pode acarretar em StackOverFlow. Então vc tento as entidades gerenciadas pelo JPA que pode ter esse tipo de relacionamento e os objetos que serão usados pelos Web Services separados facilita muito, vc pode otimizar algumas coisas, esconder outras, etc.

R

felipe_gdr:
Amigos gujeiros,

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).

Abraços!!!

De acordo.

Aliás,pros backing beans reconhecerem um EJB é só anotar com @EJB,não?

felipe_gdr

hmmm… entendi lsjunior, valeu pelo toque!!!

felipe_gdr

Exatamente Rafael. É realmente simples e rápido de desenvolver usando essa anotação.

felipe_gdr

Alguns dos argumentos são esses:

  • 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)
  • 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.)
  • 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.

R

Exatamente Rafael. É realmente simples e rápido de desenvolver usando essa anotação.

Então nesse caso,é indiferente pra aplicação JSF se o método está ou não exposto como webservice.

O problema são as implicações de segurança em expor um método que não necessariamente precisa ser exposto,como já foi comentado aqui.

O que eu quis dizer é o seguinte:

public class BackingBean(){
     @EJB
     ClasseEJB ejb;

    public void consultar(){
       ejb.consultar();
}

 
}
      
     public class EJB(){
     
        @GET
	@Path("{consultar}")
	@Produces( { MediaType.APPLICATION_XML })
        public void consultar(){

}
}

Pra aplicação JSF,que diferença faz se o método está exposto ou não?

Hebert_Coelho
  1. O tempo gasto em desenvolvimento vai ser maior com webservices. Você terá que criar o método no server, o consumidor no cliente. O consumidor pode ser por wsimport ou na unha ( oq precisa ser feito por alguém experiente em wsdl )
  2. Pode haver perda de performance. Uma lista de pessoas onde cada pessoa tem sublistas. No webservice tudo terá virar xml e depois virar objeto na view. A cada processo/consulta isso será feito.
  3. Pode expor métodos que não devam ser expostos. Se programado erroneamente você pode abrir métodos da API que não deveriam ser, risco que não se correria utilizando EJB.
  4. Tratamento de erro é mais fácil com EJB do que com Fault do Webservices (esse eu imagino que seja baseado no que eu tenho estudado)
  5. Se for para deixar o WSDL mais legível, vai rolar aí um trabalho maior para tratar o xml gerado
  6. Ao criar um método novo, é mais fácil entender uma classe java do EJB do que um método assinado no wsdl.
  7. Tratar usuário valido ou não vai ser mais complicado com webservices,

Acho que tá bom. ^^

Na boa… acho que sua empresa vai perder dinheiro ao aplicar webservice como back end para o que você nos descreveu como sendo a aplicação.

L

Isso, basta anotar.

@Named("meuMB") @ConversationScoped class MeuMB { @EJB private MeuEJB meuEJB; }

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.

Com WebServices também tem a anotação @WebServiceRef, mas não tem controle o transação que pode ter em EJBs(a chamada é atómica).

Uma coisa interessante que faço com EJBs também é o controle de acesso, quando usado com JAAS ou até mesmo criando uns interceptadores customizados.

Fiz esses customzados para evitar que um usuário chame um método caso não esteja logado ou não seja membro de uma role.

https://github.com/lsjunior/rockframework/tree/master/rockframework-faces/src/main/java/br/net/woodstock/rockframework/web/faces/security

Uso assim, barrando usuário não logados e que não estejam nas roles ROLE_A ou ROLE_B, o código para isso é bem simples mesmo.

@Logon @Role("ROLE_A", "ROLE_B") class MeuMB { }

R

Não necessariamente,com JAX-RS dá pra dispensar toda a parafernália de WSDL,Stub etc,dá uma olhada no meu post acima.

felipe_gdr

Entendi Rafael,

o problema é que o pessoal é contra usar a anotação @EJB. Eles querem que o managed bean acesse os métodos exclusivamente via Web Services.

Entendeu o drama? :shock:

Hebert_Coelho

Alguns dos argumentos são esses:

  • 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)
  • 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.)
  • 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.

  1. Basta já projetar a aplicação para ter deploy de artefatos diferentes. Realize o deploy do JSF em um war e do EJB em um EJB. Caso fosse necessário separar os sevidores, os artefatos já estariam em módulos separados. Basta apenas configurar apenas a localização de cada um.
  2. O acesso mobile em geral tem menos funcionalidades do que um acesso web. Mas com EJB é possível expor um método como webservice. Bastaria anotar o EJB e o método desejável que esse um webservice já estaria pronto.
  3. webservice não é modernidade, na verdade, é velho pra “chuchu”.
felipe_gdr

Entendi Rafael,

o problema é que o pessoal é contra usar a anotação @EJB. Eles querem que o managed bean acesse os métodos exclusivamente via Web Services.

Entendeu o drama? :shock:

felipe_gdr

Herbert, concordo com você. Inclusive a aplicação já está separada entre EAR (com os EJBs) e WAR (ManagedBeans e JSF).

Caso eu venha a colocar o EAR no servidor X e o WAR no servidor Y, como será feita a comunicação? Via RMI? Existe muita configuração a ser feita, nesse caso?

Hebert_Coelho

Não necessariamente,com JAX-RS dá pra dispensar toda a parafernália de WSDL,Stub etc,dá uma olhada no meu post acima.O JAX-RS não é acionado quando chamamos o wsimport para gerar tudo automático?
Pelo que eu tenho lido (não tenho experiência com webservices ainda) para cada novo método que é exposto como webservices é necessário executar o wsimport novamente. Não é isso?

R

Não necessariamente,com JAX-RS dá pra dispensar toda a parafernália de WSDL,Stub etc,dá uma olhada no meu post acima.O JAX-RS não é acionado quando chamamos o wsimport para gerar tudo automático?
Pelo que eu tenho lido (não tenho experiência com webservices ainda) para cada novo método que é exposto como webservices é necessário executar o wsimport novamente. Não é isso?

Não não cara,com JAX-RS é bem mais simples,olha um exemplo:

Serviço:

@Path("/venda")
public class BuscadorVenda {

	@GET
	@Path("{id}")
	@Produces( { MediaType.APPLICATION_XML })
	public Venda buscarVenda(@PathParam("id") Integer id
	){
		try {
			Venda venda = new Conexao().findById(id); 
			return venda;
		}catch(Exception e){
			e.printStackTrace();
		}

		return null;
	}
}

Para consumir um xml a partir desse serviço,basta invocar uma url host://aplicacao/consulta/venda/${id}.

R

felipe_gdr:

Caso eu venha a colocar o EAR no servidor X e o WAR no servidor Y?

Ai é que tá,existe a mais remota possibilidade disso acontecer?

Isso me lembra aquele argumento falacioso para usar JPA…“se um dia mudar o banco”

felipe_gdr

Então Rafael…

A exposição do método via WS é super fácil e rápida.

E o consumo disso? Preciso fazer um request HTTP do tipo GET ou POST, passar os parâmetros, depois pegar o retorno, tratar, etc…

Imagina fazer tudo isso no MB ao invés do simples @EJB.

Hebert_Coelho

raf4ever:
Não não cara,com JAX-RS é bem mais simples,olha um exemplo:

Serviço:

@Path("/venda")
public class BuscadorVenda {

	@GET
	@Path("{id}")
	@Produces( { MediaType.APPLICATION_XML })
	public Venda buscarVenda(@PathParam("id") Integer id
	){
		try {
			Venda venda = new Conexao().findById(id); 
			return venda;
		}catch(Exception e){
			e.printStackTrace();
		}

		return null;
	}
}

Para consumir um xml a partir desse serviço,basta invocar uma url host://aplicacao/consulta/venda/${id}.

Legal, mas desse modo aí, o nome do método deve ser o nomdo encontrado no WSDL? Isso se aplica a SOAP ou REST ou os dois? Desculpe as perguntas, quero ficar bom um dia nisso. [=

Hebert_Coelho

felipe_gdr:
Herbert, concordo com você. Inclusive a aplicação já está separada entre EAR (com os EJBs) e WAR (ManagedBeans e JSF).

Caso eu venha a colocar o EAR no servidor X e o WAR no servidor Y, como será feita a comunicação? Via RMI? Existe muita configuração a ser feita, nesse caso?

Isso, RMI. Pouca coisa. Isso varia de acordo com o servidor. [=

R

Hebert Coelho:
raf4ever:
Não não cara,com JAX-RS é bem mais simples,olha um exemplo:

Serviço:

@Path("/venda")
public class BuscadorVenda {

	@GET
	@Path("{id}")
	@Produces( { MediaType.APPLICATION_XML })
	public Venda buscarVenda(@PathParam("id") Integer id
	){
		try {
			Venda venda = new Conexao().findById(id); 
			return venda;
		}catch(Exception e){
			e.printStackTrace();
		}

		return null;
	}
}

Para consumir um xml a partir desse serviço,basta invocar uma url host://aplicacao/consulta/venda/${id}.

Legal, mas desse modo aí, o nome do método deve ser o nomdo encontrado no WSDL? Isso se aplica a SOAP ou REST ou os dois? Desculpe as perguntas, quero ficar bom um dia nisso. [=

Esqueça o WSDL nesse caso. :smiley:

felipe_gdr

Ao meu ver não. Para alcançar performance no caso de grandes clientes, imagino que clusterizar seja a prática mais reconhecida e comprovada. Mas tá difícil convencer os “chefões”, rs.

Vou preparar uma apresentação detalhada, levando-se em conta as informações valiosas que adquiri nessa discussão, e mostrar para a equipe.

Hebert_Coelho

raf4ever:
Hebert Coelho:
raf4ever:
Não não cara,com JAX-RS é bem mais simples,olha um exemplo:

Serviço:

@Path("/venda")
public class BuscadorVenda {

	@GET
	@Path("{id}")
	@Produces( { MediaType.APPLICATION_XML })
	public Venda buscarVenda(@PathParam("id") Integer id
	){
		try {
			Venda venda = new Conexao().findById(id); 
			return venda;
		}catch(Exception e){
			e.printStackTrace();
		}

		return null;
	}
}

Para consumir um xml a partir desse serviço,basta invocar uma url host://aplicacao/consulta/venda/${id}.

Legal, mas desse modo aí, o nome do método deve ser o nomdo encontrado no WSDL? Isso se aplica a SOAP ou REST ou os dois? Desculpe as perguntas, quero ficar bom um dia nisso. [=

Esqueça o WSDL nesse caso. :smiley:

Então você está falando de REST?

felipe_gdr

É porque o exemplo do Rafael usa REST, WSDL é típico de SOAP. Tô certo Rafael :wink:

R

felipe_gdr:
Então Rafael…

A exposição do método via WS é super fácil e rápida.

E o consumo disso? Preciso fazer um request HTTP do tipo GET ou POST, passar os parâmetros, depois pegar o retorno, tratar, etc…

Imagina fazer tudo isso no MB ao invés do simples @EJB.

Pois é,estão pensando num futuro que possivelmente nem irá chegar em detrimento das questões práticas da realidade atual.

R

felipe_gdr:
Então Rafael…

E o consumo disso? Preciso fazer um request HTTP do tipo GET ou POST, passar os parâmetros, depois pegar o retorno, tratar, etc…

Imagina fazer tudo isso no MB ao invés do simples @EJB.

Eu acho que esses são bons argumentos para embasar o seu ponto de vista.

Quem irá bater o martelo?

felipe_gdr

No final será do diretor do produto, que está no lado “pró-WS”. Rs

R

No final será do diretor do produto, que está no lado “pró-WS”. Rs

Ih rapaz,então a casa caiu :smiley: :smiley:

Mas não deixe de expor seus argumentos,ainda mais que vc é novato na empresa,então não deixe de se fazer notar.

R

Hebert Coelho:
raf4ever:
Hebert Coelho:
raf4ever:
Não não cara,com JAX-RS é bem mais simples,olha um exemplo:

Serviço:

@Path("/venda")
public class BuscadorVenda {

	@GET
	@Path("{id}")
	@Produces( { MediaType.APPLICATION_XML })
	public Venda buscarVenda(@PathParam("id") Integer id
	){
		try {
			Venda venda = new Conexao().findById(id); 
			return venda;
		}catch(Exception e){
			e.printStackTrace();
		}

		return null;
	}
}

Para consumir um xml a partir desse serviço,basta invocar uma url host://aplicacao/consulta/venda/${id}.

Legal, mas desse modo aí, o nome do método deve ser o nomdo encontrado no WSDL? Isso se aplica a SOAP ou REST ou os dois? Desculpe as perguntas, quero ficar bom um dia nisso. [=

Esqueça o WSDL nesse caso. :smiley:

Então você está falando de REST?

Exatamente.

rock

felipe_gdr,

de inicio está me parecendo errado o que eles estão propondo. Talvez por causa do rumo da discussão.
Se eu entendi certo, eles querem fazer com que os Managed Beans se comuniquem com a camada de negócio utilizando REST. (Parece ruim, comparando com injetar EJB)
Assim, toda a regra de negócio estaria exposta como um serviço. (Parece bom)
Dúvidas: Somente sua camada de negócio se comunica com a de persistência? então cadastros simples também necessitarão que o MB faça chamada REST?

Como quase tudo vira serviço, tem que cuidar para não cometer este erro: http://blog.xebia.com/2008/05/12/top-10-soa-pitfalls-7-incorrect-granularity-of-services/
De acordo com o artigo, os serviços devem ser divididos até a menor parte possível em que ainda faça sentido para a área de negócio.
Acho que dependendo de como for quebrada as regras de negócio nos EJBs, muitas regras não deveriam ser expostas.
Estou em dúvida neste ponto, talvez a proposta deles crie uma ótima API RESTful. :?

Mas ainda tenho a impressão que está sendo criada uma camada extra desnecessária, talvez duas, pois precisarão de algum esquema para que os serviços não sejam acessíveis por qualquer um.
Comece simples e adicione complexidade a medida que for necessário.

Outra coisa, imagina uma requisição em que o managedbean precisa executar 3, 5 ou 10 regras de negócio para dar uma resposta.
Se essas regras forem dependentes, o custo da camada REST que foi adicionada pode ser alto.
Acredito que o desempenho destas chamadas REST deve ser bem inferior ao desempenho de chamadas com injeção dos EJBs, ou seja, pode ser muito lento com REST.
Poderiam fazer uma POC sobre isto para comparar o desempenho ou talvez pesquisar mais.
Se eles não querem investir neste estudo para ter certeza que a arquitetura está ‘correta’, poderão pagar muito mais no futuro.

O que acham?

Hebert_Coelho

Exatamente.Seguindo esse caso, no lado do servidor então, ninguem precisará fazer parse do XML?

R

Exatamente.Seguindo esse caso, no lado do servidor então, ninguem precisará fazer parse do XML?

Quem consumir o serviço precisará fazer o parsing.

Hebert_Coelho

Exatamente.Seguindo esse caso, no lado do servidor então, ninguem precisará fazer parse do XML?

Quem consumir o serviço precisará fazer o parsing.Esse parse não seria um motivo para poder afirmar que o desenvolvimento pode ser mais lento?

L

Argumento tem bastante, mas se mesmo assim a empresa não aceitar daqui um tempo vc diz:
- Falei que ia dar merda, rsrsrsrs

rock

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.

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?

L

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?

felipeguerra

rock:
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.

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?


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.

felipeguerra

Essa palestra é pertinente!

felipe_gdr

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…

felipe_gdr

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

  • Falei que ia dar merda, rsrsrsrs

kkkkkkkkkk

com certeza terei essa carta sempre na manga!!!

felipe_gdr

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.)

L

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.

rock

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?

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

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).

É 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.

felipeguerra

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.

felipeguerra

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?

rock

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 } }


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…

L

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.

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.

gomesrod

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.

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…

rock

lsjunior:
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.

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.

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

Alexandre_Saudate

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

fabioFx

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.

javaflex

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!!!


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.

Criado 25 de outubro de 2012
Ultima resposta 30 de jan. de 2013
Respostas 56
Participantes 12