Devo validar a saída da API?

5

Estou trabalhando em uma API da Web para fornecer dados a terceiros de acordo com a especificação que eles forneceram.

O processo para cada chamada de API é essencialmente:
1. Extrair dados como XML
2. Desserializar dados para DTO (POCO)
3. Retornar o DTO como conteúdo de resposta (que é então serializado para o JSON por meio da negociação de conteúdo da API da Web 2)

Fui perguntado por alguém da nossa equipe de desenvolvimento para validar os DTOs.

Além de garantir que as respostas estejam em um formato que o cliente possa processar, o que já foi essencialmente realizado com a criação das classes do DTO, isso parece ser um desperdício de esforço para mim. Eu chequei o Google, mas a única validação de saída que alguém está falando é sanear valores como números de cartão de crédito e SSNs. Não me lembro de ter visto um método validar um objeto que acabou de criar antes de retorná-lo.

Como a resposta JSON é realmente apenas o XML extraído depois de ter sido desserializado e re-serializado, a única maneira de o DTO ser inválido seria se o XML extraído fosse inválido. Então, basicamente, eu estaria testando novamente as extrações em todas as chamadas.

Exceto em alguns casos em que o formato é especificado, na verdade, não sei quais valores são considerados válidos pelo cliente. O melhor que posso fazer na maioria dos casos é garantir que não haja espaços em branco. Eu essencialmente tentaria recriar cegamente a validação do cliente apenas para podermos pré-validar os dados antes que o cliente os validasse de qualquer maneira. Assumindo que eu consegui acertar, a recompensa seria apenas transferir a carga de suporte inicial para a nossa equipe porque o nosso servidor lançaria exceções de validação em vez de seu cliente <. / p>

A estrutura dos DTOs é bastante complicada. Se eu ignorar o fato de que eles estão sendo criados por meio de desserialização, a validação será complicada rapidamente. A maioria dos problemas de validação que eu teria que verificar (por exemplo, elementos de matriz nula, valores em branco) não são realmente possíveis na implementação real. O XmlSerializer não criará elementos de matriz nula, e campos de banco de dados NOT NULL não resultarão em elementos XML ausentes. Adicione 100% de cobertura de teste de unidade, e isso agora está adicionando esforço e complexidade significativos.

A validação de saída é mesmo uma prática? Eu nunca vi isso feito antes. Parece excessivamente cauteloso e preventivo. Se é uma prática, existe outro termo para isso que me ajudaria a encontrar mais informações sobre o assunto?

    
por user2097245 10.04.2015 / 02:59
fonte

2 respostas

4

I would essentially be attempting to blindly recreate the client's validation just so we could pre-validate the data before the client validated it anyway.

Fazer isso cegamente deve ser um grande sinal de alerta que você e seus clientes não chegaram a um acordo sobre o que constitui dados válidos. Se você não sabe como são os dados válidos, não pode testar seu código. Se você não pode testar seu código, não pode dizer que funciona com qualquer nível de confiança. Essencialmente, você depende dos seus clientes para encontrar seus bugs, o que não é bom.

Is output validation even a practice?

Absolutamente. Seja ou não uma prática bastante comum, está aberto para debate. : -)

A validação de saída é parte de algo chamado projeto por contrato (ou DbC ), que é um termo cunhado por Bertrand Meyer quando ele desenhou a linguagem de programação de Eiffel nos anos 80. Um dos princípios de design em torno do DbC determina que o primeiro passo no desenvolvimento de uma unidade de código é especificar quais condições devem ser satisfeitas na entrada ( pré-condições ) e sair ( pós-condições ) para execução seja considerada bem-sucedida. Essas condições, chamadas de contrato , são ferramentas extremamente poderosas para garantir que todas as partes entendam o que o código deve fazer e que ele cumpra essas promessas. O link acima contém uma descrição mais detalhada dos contratos e por que você os deseja. Eiffel e um punhado de outras línguas suportam DbC ou algo parecido diretamente; muitos outros fazem isso com asserções ou pacotes adicionais.

O que você está gerando parece complexo o suficiente para que você use uma ou mais funções para gerar cada parte. Ao dividir o todo em partes menores, especificar o que é correto para cada peça e fazer a verificação se torna um conjunto de tarefas menores e mais simples, menos propensas a erros.

Por exemplo, digamos que parte A da sua saída é composta pelas subpartes B , C e D . Se as funções que geram B , C e D puderem garantir que suas saídas estão corretas, a validação de A se tornará uma simples questão de verificar se as outras três realmente produziram algo. Se não houver validação na geração das subpartes, cabe a A verificar tudo , e isso pode ficar muito complexo muito rapidamente.

Se isso soa como uma duplicação de esforços já feitos pelo cliente, não deveria ser. Em um mundo ideal, a classe que representa B teria recursos para garantir que as entradas e saídas sejam válidas e a implementação fosse usada em ambas as extremidades da transação. Quando isso não é possível, o melhor que pode acontecer é que ambos os lados façam sua própria validação. Esse obstáculo é geralmente administrativo e não técnico. De qualquer forma, não há nada de errado com a validação extra: você está fazendo isso para garantir que o que você produz esteja correto e que o cliente faça sua própria versão para detectar seus erros.

    
por 10.04.2015 / 15:25
fonte
2

Esta é uma questão interessante e estou quase exatamente na mesma situação no momento.

Cheguei à conclusão de que é realmente necessário, porque é perfeitamente possível que você renomeie um campo no seu DTO. O que acontece depois? Você conserta o resto do seu código, faz tudo funcionar, implanta seu novo serviço da web, mas agora seu cliente reclama que seu XML está incorreto agora. Tudo funciona do seu lado, mas você não percebeu o erro.

Meu serviço da web retorna JSON, mas é o mesmo princípio. Eu tenho um teste de unidade que instancia o controlador WebApi, chama o método e recupera o resultado como JSON e verifique se o resultado está correto. Se você escarnecer e arquivar seus dados, poderá garantir que todo o resultado retornado seja exatamente o esperado. Lembre-se de que você não está testando o código de serialização do .NET WebApi, não está testando se os valores de saída estão corretos, está testando que a saída do seu serviço da Web está sintaticamente correta (campos XML estão aninhados corretamente e nomeados corretamente) .

Eu diria que com XML é tão provável (possivelmente mais provável) que você acidentalmente pode alterar o formato sem nem perceber e interromper o serviço para o (s) seu (s) cliente (s). Então, sim, vá em frente, valide.

    
por 10.04.2015 / 03:16
fonte

Tags