Flexibilizando a requisição e resposta à serviços REST


Ao criar um serviço WCF para ser acessado através do modelo REST, devemos decorar as operações que o compõem o contrato com os atributos WebGetAttribute ou WebInvokeAttribute, dependendo de como as requisições devem chegar até elas.

As requisições para estas operações podem ser enviadas e recebidas através de dois formatos: Xml ou Json, e para configurar isso, podemos recorrer à duas propriedades fornecidas pelos dois atributos listados acima. Essas propriedades são: RequestFormat e ResponseFormat, onde ambas recebem uma das opções expostas pelo enumerador WebMessageFormat.

Isso quer dizer que devemos definir, de forma estática, o formato que a mensagem será aceita e como ela será devolvida para os clientes. O grande problema desta técnica é que as vezes você pode ter um mesmo serviço sendo consumindo por clientes diferentes, que lidam melhor com um formato específico. Por exemplo, você pode ter um mesmo serviço sendo consumido por uma aplicação Silverlight, que possui um suporte melhor ao Xml, e ao mesmo tempo, o mesmo serviço sendo consumido por um código jQuery, que lida melhor com o formato Json. Para tornar o serviço flexível, tínhamos que fazer isso de forma imperativa, ou seja, dentro da implementação da operação, tínhamos que validar qual o formato desejado pelo cliente, e com isso especificar no contexto da requisição qual o formato que deve ser utilizado pelo runtime do WCF para gerar o resultado. O código abaixo ilustra de forma resumida essa condição:

public class Servico : IContrato
{
    public string Ping(string value)
    {
        WebOperationContext.Current.OutgoingResponse.Format =
            VerificarFormato(…) == “json” ? WebMessageFormat.Json : WebMessageFormat.Xml;

        return “resultado da operação”;
    }
}

Geralmente o formato é fornecido por uma query string adicional ou analisando os headers da requisição HTTP, que informa o formato através do content-type. O código acima permite definirmos o formato da resposta baseando-se na preferência do usuário, mas como podemos perceber, há muito código para avaliar isso, e me obriga a misturar a minha implementação com código de infraestrutura.

Para facilitar, a Microsoft criou na versão 4.0 do WCF, uma nova propriedade na classe WebHttpBehavior, chamada AutomaticFormatSelectionEnabled. Trata-se de uma propriedade boleana, que quando definida como True, irá interpretar a requisição e gerar a resposta no mesmo formato estipulado pelo cliente, olhando para a propriedade content-type que está nos presente nos headers da requisição. Para habilitar, podemos recorrer ao seguinte código:

<?xml version=”1.0″?>
<configuration>
  <system.serviceModel>
    <services>
      <service name=”Service”>
        <endpoint
          address=””
          binding=”webHttpBinding”
          contract=”IService”
          endpointConfiguration=”edpConfig” />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name=”edpConfig”>
          <webHttp automaticFormatSelectionEnabled=”true” />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Com esta opção habilitada, meu contrato fica totalmente independente do formato, ou seja, se o cliente está requisitando em formato Json, o WCF será capaz de acatar a requisição, processá-la e devolver o resultado no mesmo formato. O mesmo acontece com o Xml. Finalmente, você pode ter um único serviço sendo capaz de receber e retornar mensagens no mesmo formato do cliente, não os obrigando mais ele a trabalhar com o formato específico, que as vezes diferente daquele que é o mais comum.

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s