Agora, se ao definir o header accept como sendo application/json, as empresas serão retornadas em formato Json, facilitando o consumo através de aplicações Javascript:
Uma das boas práticas que temos hoje ao construir qualquer classe, seja ela para servir ou não como um serviço, é desenhá-las separando as responsabilidades de cada uma delas, e tornando o acoplamento entre elas cada vez menor, para que assim possamos ter um código simples de evoluir e manter.
Como o uso de serviços é comum nos dias de hoje, é importante que também se crie serviços baseando-se nestes princípios. Para isso, precisamos de um ponto de estensibilidade que permita interceptar a criação das classes que representam o serviço, e com isso, utilizarmos algum container de injeção de dependência para abastecermos todas as necessidades do serviço que está sendo exposto, para que ele esteja pronto para atender a requisição.
Quando utilizamos o WCF puro, o ponto de estensibilidade que permite isso é através da implementação da interface IInstanceProvider. Nesta nova API, temos um ponto de estensibilidade para fornecer a instância da classe que representa o serviço, e ali acoplarmos um código customizado. Para exemplificar, vamos incrementar a classe do serviço que fizemos acima (ServicoDeProspeccao), passando agora a depender de uma classe que é a implementação concreta de algum repositório. Temos dentro da classe um membro privado chamado repositorio do tipo IRepositorio. Esse repositório é utilizando no interior dos métodos RecuperarEmpresasEmProspeccao e Adicionar, carregando ou salvando os dados da implementação do repositório concreto que será injetado.
Se repararmos, o membro repositorio está decorado com o atributo ImportAttribute. Esse atributo é fornecido pelo MEF (Managed Extensibility Framework), que se baseia nestes metadados para relacionar e abastecer o membro com a instância de uma classe que implementa esta interface (IRepositorio). Como exemplo, vamos criar um repositório em memória, que armazena os dados em uma lista, e também através de um atributo (ExportAttribute), indicaremos ao MEF que essa classe é uma implementação concreta da interface IRepositorio.
Ainda é necessário configurar o container do nosso framework de injeção de dependência, que neste caso, é o MEF. Para isso, vamos recorrer a interface IResourceFactory, que está disponível por essa nova API. Essa interface fornece apenas dois métodos autoexplicativos: GetInstance e ReleaseInstance. O que fazemos no interior do método GetInstance é instanciar a classe que representa o serviço (ServicoDeProspeccao) e recorrer ao container para resolver as dependências do mesmo. Depois disso, retornamos o objeto já configurado para o WCF poder proceder com a execução da requisição.
Só que isso ainda não é o suficiente. Precisamos indicar ao WCF para ele recorrer à esta factory para construir o serviço. E para isso, vamos utilizar um overload do método MapServiceRoute, que além do prefixo do serviço, recebe a instância da classe HttpHostConfiguration, que representa a configuração do host do serviço, obviamente de uma forma muito mais simplificada do que aquela que é utilizada pelo WCF. Essa classe fornece um método chamado SetResourceFactory, que como o próprio nome diz, recebe ou cria a instância da classe que representa o construtor de instâncias do serviço, que no nosso caso é aquela que acabamos de criar: MEFResourceFactory. Aquela configuração que tínhamos acima no arquivo Global.asax, agora passa a figurar da seguinte forma:
Como sabemos, a construção de serviços WCF possibilita criarmos um contrato e, consequentemente, uma classe que representará o serviço, que por sua vez, deve implementar aquele contrato que descreve as funcionalidades expostas por ele. Ao utilizar esta técnica, construimos nosso contrato utilizando tipos simples (inteiro, decimal, boleano, etc.) ou até mesmo tipos complexos, que são classes contendo as propriedades que levam de um lado ao outro lado a informação em uma forma mais “tipada”.
Apesar disso ser interessante, e ser um grande diferencial do WCF, isso acaba sendo um problema ao trabalhar com serviços REST. Isso se deve ao fato de que há a necessidade de ter o controle total do HTTP, que é possível com o WCF puro, mas mais uma vez, exige um conhecimento de baixo nível para conseguir manipular o protocolo e suas respectivas características.
Com o intuito de facilitar e trazer, novamente, o controle para o desenvolvedor, a Microsoft inclui nesta API classes que representam a mensagem de requisição (HttpRequestMessage) e de resposta (HttpResponseMessage). Cada uma dessas classes trazem várias propriedades, onde cada uma delas expõe características do protocolo HTTP, tais como: Content, Headers, Method, Uri, StatusCode, etc.
O serviço passará a utilizar essas classes em suas operações, ou seja, receberá um parâmetro do tipo HttpRequestMessage, que possui todas as informações necessárias solicitadas pelo cliente, enquanto o retorno será do tipo HttpResponseMessage, que será onde colocaremos todas as informações de resposta para o mesmo cliente, sendo essas informações o resultado em si, o código de status do HTTP, eventuais headers, etc. Para exemplificar, vamos analisar o método Ping abaixo:
O ponto importante a se notar é a criação da classe HttpResponseMessage, que em seu construtor receber o código de status do HTTP, e logo em seguida, temos a propriedade Content, que como já suspeitamos, deve receber o resultado da operação a ser enviada para o cliente. Há uma classe abstrata que define a estrutura de um conteúdo de retorno, chamada de HttpContent. Já existem algumas implementações concretas desta classe nesta API, e uma delas é a StringContent, que recebe uma string e será devolvida para o cliente no corpo da resposta HTTP.