WSDL (VI) – wsdl:binding

Esta entrada es la sexta entrega dedicada al interesante mundo del WSDL. En esta entrada encontrarás en detalle el elemento wsdl:binding, que contiene los detalles sobre el formato del mensaje, así como del protocolo utilizado para transportar la información tanto de entrada como de salida.

Descripción

Wsdl:binding forma parte del objeto wsdl:definitions.

El elemento wsdl:binding define el formato del mensaje y los detalles del protocolo que se utiliza en los diferentes procesos de comunicación del servicio web. Es posible definir diferentes bindings asociados al mismo portType, por lo que un mismo servicio web puede implementar la comunicación a través de diferentes protocolos y dentro de cada operación definir diferentes configuraciones para la comunicación de entrada y de salida.

El tipo de binding elegido puede influir en la compatibilidad multiplataforma del servicio web 

Gramática

La gramática del elemento wsdl:types es la siguiente (? –> es opcional, * –> pueden ser de 0 a N elementos):

<wsdl:binding name="nmtoken" type="qname"> *
 <-- extensibility element (1) --> *
 <wsdl:operation name="nmtoken"> *
 <-- extensibility element (2) --> *
 <wsdl:input name="nmtoken"? > ?
 <-- extensibility element (3) --> 
 </wsdl:input>
 <wsdl:output name="nmtoken"? > ?
 <-- extensibility element (4) --> *
 </wsdl:output>
 <wsdl:fault name="nmtoken"> *
 <-- extensibility element (5) --> *
 </wsdl:fault>
 </wsdl:operation>
 </wsdl:binding>

Atributos

El elemento wsdl:binding cuenta con los siguientes atributos:

  • name: este atributo proporciona un nombre único que identifica el binding dentro del documento WSDL
  • type: este atributo enlaza el elemento wsdl:binding con el portType definido, de hecho, deben llevar el mismo nombre.

SubElementos

El elemento «extensibility element (1)» indica el tipo de binding que se elige para las operaciones especificadas. Cada elemento wsdl:binding solo puede hacer referencia a un único protocolo. Esto se hace indicando cualquiera de estos tres elementos:

  • <soap:binding style=»document | rpc» transport=»http://schemas.xmlsoap.org/soap/{http | smtp | ftp}»/>
  • <http:binding verb=»GET | POST»>
  • <mime:multipartRelated>
El primer binding es un binding basado en el protocolo SOAP. El segundo binding está basado en GET y POST de http y el último es el binding MIME que suele ir siempre ligado a mensajes de INPUT/OUTPUT de operaciones SOAP.  
 
El elemento wsdl:operation describe la operación sobre la que se va a aplicar información de binding. Esta información viaja en el elemento «extensibility element (2)» que detallará la información de binding propia de la operación.
 
El elemento wsdl:input describe el objeto de entrada al que se va a aplicar información de binding. Esta información viaja en el elemento «extensibility element (3)» que detallará la información de binding para el objeto de entrada de esta operación. 
 
El elemento wsdl:output describe el objeto de respuesta al que se va a aplicar información de binding. Esta información viaja en el elemento «extensibility element (4)» que detallará la información de binding para el objeto de respuesta de esta operación.
 
El elemento wsdl:fault describe en caso de fallo las características de binding. Esta información viaja en el elemento «extensibility element (5)» que detallará la información de binding para el objeto de error.
 

Ejemplo de SOAP Binding.

Este ejemplo muestra la definición de un binding para el portType AsistenteProducto. 

<wsdl:binding 
   name="AsistenteProductoSWSoapBinding" 
   type="tns:AsistenteProducto">
 <soap:binding 
    styledocument«    
 <wsdl:operation nameconsultaInteraccionesTratamientoCompleto«>     
   <soap:operation 
     soapAction/consultaInteraccionesTratamientoCompletoOP«          
     styledocument«/>
  <wsdl:input nameconsultaInteraccionesTratamientoCompleto«         
     <soap:body useliteral«/>
  </wsdl:input>
  <wsdl:output nameconsultaInteraccionesTratamientoCompletoResponse«>
    <soap:body useliteral«/>
  </wsdl:output>
 </wsdl:operation>
 <wsdl:operation nameconsultaDuplicidadesTratamientoNuevo«>
  <soap:operation 
      soapAction/consultaDuplicidadesTratamientoNuevoOP«      
      styledocument«/>
  <wsdl:input nameconsultaDuplicidadesTratamientoNuevo«>
    <soap:body useliteral«/>
  </wsdl:input>
  <wsdl:output nameconsultaDuplicidadesTratamientoNuevoResponse«>
    <soap:body useliteral«/>
  </wsdl:output>
 </wsdl:operation>
 <wsdl:operation nameconsultaDuplicidadesTratamientoCompleto«>
  <soap:operation 
      soapAction/consultaDuplicidadesTratamientoCompletoOP«       
      styledocument«/>
  <wsdl:input nameconsultaDuplicidadesTratamientoCompleto«>
    <soap:body useliteral«/>
  </wsdl:input>
  <wsdl:output nameconsultaDuplicidadesTratamientoCompletoResponse«>
    <soap:body useliteral«/>
  </wsdl:output>
 </wsdl:operation>
 <wsdl:operation nameconsultaInteraccionesTratamientoNuevo«>
  <soap:operation 
     soapAction/consultaInteraccionesTratamientoNuevoOP«    
     styledocument«/>
  <wsdl:input nameconsultaInteraccionesTratamientoNuevo«>
    <soap:body useliteral«/>
  </wsdl:input>
  <wsdl:output nameconsultaInteraccionesTratamientoNuevoResponse«>
    <soap:body useliteral«/>
  </wsdl:output>
 </wsdl:operation>
</wsdl:binding>

En el ejemplo se puede ver que el binding es de tipo SOAP a través de HTTP. El estilo de SOAP en este caso es document.  Si no se pone nada, el estilo seguirá siendo «document«.  

<wsdl:binding 
   name="AsistenteProductoSWSoapBinding" 
   type="tns:AsistenteProducto">
 <soap:binding 
    style="document"    
    transport="http://schemas.xmlsoap.org/soap/http"/>

Podemos ver que cada operación puede definir un SOAP style propio, teniendo como posibles valores también RPC y DOCUMENT. En el ejemplo no se indica, por defecto el estilo es document. El campo soapAction especifica el valor de cabecera SOAPAction. En el caso de protocolo SOAP sobre HTTP, el valor SOAPAction de la cabecera es obligatorio, por lo que siempre habrá que rellenarlo. 

<soap:operation 
  soapAction="/consultaDuplicidadesTratamientoNuevoOP"      
    style="document"/>

Cada elemento que conforma la operación, wsdl:input, wsdl:output o wsdl:fault definen el elemento soap:body. Este elemento especifica como se incluyen los elementos wsdl:parts en el elemento SOAP Body.  El atributo use marca la codificación que se realiza en la información, y puede ser literal o encoded. En el ejemplo, el objeto de entrada de consultaInteraccionesTratamientoNuevo la codificación del body se realiza de forma literal

<wsdl:input name="consultaInteraccionesTratamientoNuevo">
    <soap:body useliteral«/>
</wsdl:input>

 

DOCUMENT versus RPC

A la hora de especificar dentro de las operaciones SOAP como queremos que se vea el mensaje transportado la definición del atributo style de la etiqueta soap:binding o soap:operation (si queremos aplicar un estilo diferente por cada operación) es la clave. 

El atributo style puede tomar dos posibles valores: document y rpc (remote procedure call). 

Un mensaje SOAP de estilo RPC se construye con la idea de invocar al servicio web como si fuera un método de una aplicación. Por tanto, el cuerpo del mensaje SOAP contiene un elemento XML por cada parámetro que necesita el método y estos elementos de parámetro se incluyen en otro elemento superior que representa el nombre del método al que se llama. El WSDL para una operación codificada en RPC es menos compleja que sus hermanas codificadas en estilo DOCUMENT. 

Un ejemplo de mensaje SOAP RPC es:

<soap:envelope>
  <soap:body>
    <multiply>    <!-- web method name -->
      <a>2.0</a>  <!-- first parameter -->
      <b>7</b>    <!-- second parameter -->
    </multiply>
  </soap:body>
</soap:envelope>

Un mensaje SOAP de estilo DOCUMENT, sin embargo, no contiene restricciones en la construcción del cuerpo del mensaje. Permite la inclusión libre de datos en formato XML representados por un Schema XML. De esta forma, el cliente y el proveedor son los encargados de hacer el trabajo de marshall y unmarshall. Esto contrasta con RPC donde este trabajo de marshal y unmarshall debe ser realizado por la librería SOAP que se esté utilizando. 

Un ejemplo de mensaje SOAP DOCUMENT es:

<soap:envelope>
  <soap:body>
    <!-- arbitrary XML -->
    <movies xmlns="http://www.myfavoritemovies.com">
      <movie>
        <title>2001: A Space Odyssey</title>
        <released>1968</released>
      </movie>
      <movie>
        <title>Donnie Darko</title>
        <released>2001</released>
      </movie>
    </movies>
  </soap:body>
</soap:envelope>

 

La gran ventaja de RPC sobre DOCUMENT es que es fácilmente interpretable por humanos. Sin embargo, esta ventaja no es tal, ya que no tiene gran utilidad que los humanos podamos leer de forma fácil los WSDL.

Por otro lado, esta ventaja, se convierte en desventaja debido al acoplamiento tan fuerte que hay con el código de la aplicaciónlo. Esto quiere decir, por ejemplo,  que si se quiere realizar un cambio en el orden de los parámetros implica irremediablemente un cambio en la definición del servicio web. 

Sin embargo, el estilo DOCUMENT tiene un acoplamiento muy débil con el código de la aplicación. La gran ventaja es que cambios realizados en el orden de los parámetros o incluso en el tipo de los mismos no influyen en la definición del servicio web. La desventaja  es que el SOAP generado es más difícil de interpretar visualmente por una persona (lo que tampoco tiene porque ser una gran desventaja).

Además, el que no haya reglas específicas para la generación de SOAP en el estilo DOCUMENT es una ventaja/desventaja. Es ventaja porque nos permite libertad total a la hora de codificar la información y es una desventaja porque el trabajo de MARSHALL y UNMARSHALL recae en el cliente y en el proveedor.

Encoded versus Literal

La otra gran opción a la hora de determinar el aspecto final del código SOAP generado es el atributo use del elemento soap:body, que puede tomar valores encoded o literal.

El uso Literal implica que el cuerpo SOAP sigue un esquema XML para definir su contenido. Este esquema XML se incluye en el apartado wsdl:types del WSDL. Por tanto, siempre que el cliente tenga acceso al WSDL sabrá como debe hacer el marshall/unmarshall del documento.

El uso Encoded, sin embargo, implica que el cuerpo SOAP no sigue ningún esquema XML, aunque tenga que seguir un formato específico que incluya la información para que el cliente sepa como hacer el marshall y el unmarshall de la información. El modo encoded no es recomendable y no está aceptado por el estándar WS-I, debido a las incompatibilidades que las diferentes implementaciones SOAP hagan en los diferentes frameworks de servicios web y los diferentes lenguajes de programación.

Conclusión

El apartado wsdl:binding es el qué más problemas de incompatibilidad puede dar en el uso multiplataforma de un servicio web. En él se define el protocolo utilizado en la comunicación, así como la codificación de la información que viaja por cada operación. 

Es recomendable que la codificación se realice siempre en estilo DOCUMENT y uso LITERAL. De esta forma nos aseguramos libertad en el envío de la información y garantizamos que dicha información cumple un esquema que facilita el tratamiento de la misma.

Links