Mixing REST and SOAP
A proposito del TechEd 2008, estuve invitado como parte del equipo de Arquitectura en el "Ask The Experts", fue un evento fabuloso, y algo que quedo en el tintero fue el uso de WCF en .NET 3.5. De alli en mas inmediatamente gracias al apoyo de mis alumnos en el curso de Taller que dicto en USIL (www.usil.edu.pe) empezamos a implementar muchas de las caracteristicas. Una de ellas es REST, tambien con algo de JQuery (para mejorar Ajax) y claro esta JSON. Pero un reto y tarea pendiente que tenia era implementar servicios usando DuplexBinding, una sugerencia que recibi de Shy Cohen de Microsoft sobre una pregunta de arquitecturas basadas den Firewall NAT. Bueno espero que puedan tener todo listo para la presentacion en dos semanas :)
De este experimento recibi una consulta interesante de uno de mis alumnos (Jonathan Chavez) sobre el uso de REST. Nuestro proyecto considera el uso de REST con WCF, antes de eso habiamos trabajado bajo el modelo de la fabrica de Software para modelar los contratos. La pregunta es: Como mezclar REST y SOAP?, es decir de que manera se pueden exponer los servicios sin tener que programar o modelar dos veces el servicio.
Que sucede si queremos alojar el mismo servicio WCF usando SOAP y REST?. De hecho un solo contrato de servicio y su implementacion pueden manejar ambos tipos de "requests".
- REST se basa en un modelo de servicio que permite mapear a un URL una operacion particular, SOAP se basa en un "action header" dentro del mensaje.
- Los mensaje REST pueden ser formateados como XML o JSON, los mensajes SOAP pueden ser serializados como binarios, XML o MTOM
Al decorar los contratos con WebGetAttribute o WebInvokeAttribute se puede especificar el UriTemplate para el mapeo de las operaciones a los URLs. Los mismos atributos permiten definir la serializacion JSON o XML.
Estos atributos son ignorados a menos que se habilite el WebHttpBEhavior para un "endpoint". Entonces si se expone dos endpoints para el mismo contrato, se puede configurar uno para REST y el otro para SOAP. La direccion para cada uno debe ser unica, como por ejemplo:
<services>
<service name="ServicioCliente">
<endpoint address="http://localhost:8000/ServicioCliente/REST" binding="webHttpBinding" contract="Contrato.IServicioCliente"/>
<endpoint address="http://localhost:8000/ServicioCliente/SOAP" binding="wsHttpBinding" contract="Contrato.IServicioCliente"/>
</service>
</services>
La configuracion usa WebHttpBinding para /Rest y WsHttpBinding para Soap.
- Se pueden exponer ambos endpoint usando WebService-Host en lugar de ServiceHost. El siguiente codigo muestra como en un "self-host" (una aplicacion de consola, o windows, o un servicio windows, etc.) se puede hacer.
WebServiceHost ohost=new WebServiceHost(typeof(Servicios.ServicioCliente));
ohost.Open();