WCF Simplified Part 9: SOAP, WSDL, and REST
May 27, 2010 5 Comments
Today we’ll look at some of the basic concepts in web services so that we can have a better understanding of how WCF works.
1. SOAP 1.2: SOAP stands for Simple Object Access Protocol. It is simply an XML document that describes a message (structured and typed information) that can be sent from one network endpoint to another. SOAP is fundamentally a stateless, one-way message exchange paradigm, but applications can create more complex interaction patterns (e.g., request/response) by combining such one-way exchanges with features provided by an underlying protocol and/or application-specific information. A SOAP message may be transferred by different underlying protocols for example, for web-based access, it could be placed in the body of a HTTP POST request. The schema for the SOAP XML can be found here. The structure of a SOAP message looks like this,
<?xml version='1.0' ?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <!-- The header is optional. It contains contextual information related to the message --> <soap:Header> </soap:Header> <!-- The body is mandatory --> <soap:Body> <!-- Sample content --> <ns:GetPassengerName xmlns:ns="http://someURI"> <ns:PassengerId>815</ns:PassengerId> </ns:GetPassengerName> </soap:Body> </soap:Envelope>
And another could look like,
<?xml version='1.0' ?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <!-- The body is mandatory --> <soap:Body> <!-- The body has content --> <ns:GetPassengerNameResponse xmlns:ns="http://someURI"> <ns:PassengerName>John Locke</ns:PassengerName> </ns:GetPassengerNameResponse> <!-- or can report a fault --> <soap:Fault> <soap:Code> </soap:Code> <soap:Reason> </soap:Reason> <soap:Detail> </soap:Detail> </soap:Fault> </soap:Body> </soap:Envelope>
The above example is a little contrived, it’s recommended that you use URIs as resource identifiers, so your host might look like http://someHOST/somePATH?PassengerNameFromID=815.
The SOAP-HTTP binding is of particular interest because it is widely used.
a. SOAP HTTP GET example,
GET /somePATH?PassengerNameFromID=815 HTTP/1.1 Host: someHOST Accept: text/html;q=0.9, application/soap+xml
with a response,
HTTP/1.1 200 OK Content-Type: application/soap+xml; charset="utf-8" Content-Length: [...] <?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Body>[...]</env:Body> </env:Envelope>
b. SOAP HTTP POST example,
POST /somePATH HTTP/1.1 Host: someHOST Content-Type: application/soap+xml; charset="utf-8" Content-Length: [...] <?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" > <env:Body>[...]</env:Body> </env:Envelope>
2. WSDL 1.1: WSDL stands for Web Services Description Language. It is simply an XML document that describes a web service. The schema for the WSDL XML is publicly available here. The WSDL XML needs to describe fully how communication between two network endpoints will occur. It is a binding mechanism, it attaches a specific protocol or format to a message, operation or endpoint. The major parts of the WSDL XML are,
<?xml version="1.0" encoding="UTF-8"?> <definitions name="HelloService"> <types> <!-- What data types are exchanged --> </types> <message> <!--What messages are exchanged --> </message> <portType> <!-- What operations are supported by the web service --> </portType> <binding> <!-- How the messages will be transmitted --> </binding> <service> <!-- Where is the web service located --> </service> </definitions>
Say you have a service contract,
[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); }
The corresponding WSDL looks like (some things omitted for clarity),
<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions name="Service1" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" [...]> <!-- The two messages GetData and GetDataResponse (because IsOneWay is false) --> <wsdl:message name="IService1_GetData_InputMessage"> <wsdl:part name="parameters" element="tns:GetData"/> </wsdl:message> <wsdl:message name="IService1_GetData_OutputMessage"> <wsdl:part name="parameters" element="tns:GetDataResponse"/> </wsdl:message> <!-- The web service only has one operation - GetData --> <wsdl:portType name="IService1"> <wsdl:operation name="GetData"> <wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/> </wsdl:operation> </wsdl:portType> <!-- Note the WSHttpBinding --> <wsdl:binding name="WSHttpBinding_IService1" type="tns:IService1"> <wsdl:operation name="GetData"> <wsdl:input> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_Input_policy"/> </wsdl:input> <wsdl:output> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_output_policy"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <!-- The address for the web service --> <wsdl:service name="Service1"> <wsdl:port name="WSHttpBinding_IService1" binding="tns:WSHttpBinding_IService1"> <wsa10:EndpointReference> <wsa10:Address>http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary2/Service1/</wsa10:Address> <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"> <Dns>localhost</Dns> </Identity> </wsa10:EndpointReference> </wsdl:port> </wsdl:service>
3. REST: REST stands for Representational State Transfer. REST is basically a set of design principles for web services. Since it’s not a protocol (like SOAP), it doesn’t specify any new XML or schema but relies on HTTP’s methods (GET/POST/PUT/DELETE). The idea is to design (REST-ful) web services that deal with identifying and manipulating resources using HTTP methods. is to use The four main tenets of REST are,
a. Use HTTP methods correctly: This means use the methods GET/POST/PUT/DELETE for what they are meant for. For example, GET should be a safe retrieval with no side effects.
b. Be Stateless: Design the host and client so that the HTTP headers and body of a request contains all of the parameters, context, and data needed by the server-side component to generate a response. A stateless service shifts most of the responsibility of maintaining state to the client application.
c. Expose self-documenting (directory structure-like) URIs: For example, http://someHOST/photos/2010/05/27/{id}
d. Use MIME types and HTTP Accept: RESt-ful services usually use the common content types application/json or application/xml.
Thank you for simple and short, but very usefull post!
11. This is really interesting, You are a very skilled blogger. I have joined your feed and look forward to seeking more of your great post. Also, I’ve shared your web site in my social networks!
I get pleasure from, result in I found exactly what I used to be looking for. You’ve ended my four day lengthy hunt! God Bless you man. Have a great day. Bye
The blog sounds good. I would appreciate if could provide more detailed example for using HTTP GET with Soap 1.2?
Great information you possess shared. I furthermore found similar weblog like yours which was amazing. Have a look at it if possible.