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.