Dúvida - Boas práticas no retorno de web services

Olá,

estou começando a estudar webservices e vi uma situação com diversas soluções em tutoriais pela net, que me deixaram com dúvidas em relação a boas práticas.

Quando eu quiser retornar uma mensagem de erro/aviso para quem estiver consumindo o meu webservice, eu devo enviar via exceção ou em uma string?

Simulando essas situações, com um serviço que disponibiliza um cliente pelo CPF.

[code]public Cliente obterCliente(String cpf) throws MinhaExcecao {

	Cliente cliente = procuraClienteBD(cpf);

	if (cliente == null) {
		throw new MinhaExcecao("Cliente nao encontrado");
	}

	return cliente;
}[/code] 

[code]public Cliente procurarCliente(String cpf) {

	Cliente cliente = procuraClienteBD(cpf);

	if (cliente != null) {
		cliente.setMensagem("OK");
	} else {
		cliente = new Cliente();
		cliente.setMensagem("Cliente nao encontrado");
	}

	return cliente;
}[/code]

Esses casos seriam dois exemplos que já vi na net, um retornando a mensagem de que não encontrou cliente por uma exceção e um outro dentro do próprio objeto.
No caso do retorno pela exceção, vi vários casos, mas pensando em um serviço bem genérico, acho estranho já que nem todas linguagens possuem Exception.

Agradeço a colaboração

Cara, eu li uns livros e eles falam que Exception só deve ser criada quando acontece erro mesmo.
Ex.: Um arquivo deveria estar em um local que não está, conexão não encontrada, falta de parâmetros e tals.

Caso seja um erro de regra de negócio mesmo, deveria ser retornado uma mensagem informando o problema.

obrigado pela resposta jakefrog, eu imaginava a mesma coisa, achei estranho pq vi vários casos assim.

e quando você diz que tinha que ser por msg, seria no caso do método procurarCliente()?

Nesse caso (defendendo OO aos meus olhos) essa mensagem não tem na haver com o Cliente (objeto dentro do sistema) correto?
A classe deve saber apenas dela e não de nada do que acontece ao seu redor.

Então se seu cliente externo necessita de um retorno, seria melhor você criar um ClienteDTO (DTO = DataTransferObject) e dentro dele teria:

public class ClienteDTO{ private class Cliente; private String mensagem; // get/seters }

Assim, sua classe Cliente permanece como deve ser.

E como você está falando de boas práticas, se lembre de sempre programar para interface.

Ao invés de enviar uma classe para o cliente, envie uma Interface que sua classe implemente.
Vai te livrar de muitas dores de cabeças vindouras. [=

como diria meu professor.

“Exatamente isso meu amigo…”

muito obrigado pela resposta jakefrog.

Cara, nao sei se é a melhor opção essa minha.

Na empresa que eu trabalhei um dos webservices que consumiamos era em c# ai sempre rolava um stress com o tipo, pq a parte cliente era java.
Qual foi a solução, criamos uma classe com atributos mais simples possiveis.

Nessa classe tinhamos um atributo que era booleano que retorna o status da operação, true e false.
Tinhamos tambem um atributo denominado Erro, que era uma String.

nunca passamos uma exception para o webservice. sempre tratamos os erros lado server e passamos as mensagens para o cliente. Achamos melhor assim por alguns motivos:

Primeiro compatibilidade, fica mais facil de trabalhar com qualquer linguagem.
Segundo, vai que o sistema ja esta em produção e vc quer mudar alguma coisa no seu server e muda a exception ou acresenta, voce vai ter que gerar o cliente novamente.

Entao vc cria uma classe mais generica de retorno que voce possa mudar o seu server sem alterar o seu cliente.

É so uma dica!!!

Não sou um expert em web service e não sei o que a teoria diz a respeito, mas o que se observa no dia-a-dia é que as exceções causam alguns problemas.

Dependendo do framework utilizado (tanto para construir o lado server como o client) elas podem não ser mapeadas corretamente. No Axis por exemplo, você cria toda a estrutura para utilização de exceções de negócio mas no fim das contas qualquer exceção chega no cliente como AxisFault e não tem como saber se o que aconteceu foi exceção de negócio ou um erro imprevisto.

O que eu faria tem a ver com as dicas que o jakefrog e o vcsmetallica já deram anteriormente, que é um retorno mais ou menos assim:

class RetornoConsultaCliente {
   boolean sucesso; // True se deu tudo certo
   String mensagem; // Contem a mensagem de erro caso tenha algum
   Cliente cliente; // A informacao solicitada.

As exceçoes ficariam só para o caso de dar pau realmente.