c# - studio - ¿Cuál es la mejor práctica al diseñar SOA WCF web-services?
wcf visual studio 2017 (4)
Dado un contrato de operación como:
[OperationContract]
void Operation(string param1, string param2, int param3);
Esto podría ser rediseñado para:
[MessageContract]
public class OperationRequest
{
[MessageBodyMember]
public string Param1 { get; set; }
[MessageBodyMember]
public string Param2 { get; set; }
[MessageBodyMember]
public int Param3 { get; set; }
}
[MessageContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
Una cosa que me gusta de MessageContract es que tengo un control un poco más explícito sobre el formato del mensaje SOAP.
Del mismo modo, podría escribir casi el mismo código, pero usar un DataContract:
[DataContract]
public class OperationRequest
{
[DataMember]
public string Param1 { get; set; }
[DataMember]
public string Param2 { get; set; }
[DataMember]
public int Param3 { get; set; }
}
[DataContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
Una cosa que me gusta de DataContract es que puedo definir IsRequired, Order y Name.
Hoy espero que el único consumidor sea un cliente de WCF. Sin embargo, quiero diseñar un contrato primero y cumplir con las prácticas de SOA tanto como sea posible. En lugar de que WCF dicte mi SOAP, WSDL y XSD, quiero que el XML defina la capa WCF, pero use WCF para generar esto para no agregar ningún procesamiento de mensaje personalizado a WCF. Quiero seguir las convenciones XML de SOA más comunes, que creo que probablemente sean todas las etiquetas que comiencen en minúsculas, ¿estoy en lo cierto? Y quiero ser lo más tolerante a las versiones posible.
¿Es aconsejable crear siempre mensajes de solicitud y respuesta como este? ¿Cuál de los tres formatos promueve las mejores prácticas de SOA? ¿Debo ir un paso más allá y definir tanto un DataContract como un MessageContract por los cuales el MessageContract solo contiene el DataContract? ¿O debería usar DataContracts solo si realmente estoy exponiendo un nuevo tipo (es decir, no creo tipos de mensajes como contenedores)?
Un conjunto cargado de preguntas que conozco, pero estoy tratando de llegar al meollo del asunto, y no estoy seguro de si separar las preguntas proporciona un contexto suficiente para obtener la respuesta que estoy buscando.
Creo que honestamente depende del escenario. Si solo está intercambiando tipos simples [es decir, cadena], OperationContract es ciertamente aceptable.
Debe usar MessageContract cuando desee modificar el formato del mensaje y DataContract se debe aprovechar cuando desee expresar un Tipo complejo, como una dirección.
YAGNI viene a la mente aquí.
Yo digo que no exageres al mirar demasiado bien hacia el futuro. WCF ya es muy amigable con SOA. Digo, en general, mantener los valores predeterminados y tener cuidado con el acoplamiento hasta que tenga una necesidad específica de hacer algo complicado.
Siempre es una buena práctica no tener múltiples parámetros en un contrato de operación, siempre tener un tipo que envuelva todos los parámetros requeridos, esto ayudará en el largo plazo. Sus clientes existentes no se romperán cuando agregue un nuevo parámetro opcional.
Trabajo en un equipo de integración de negocios en el que nos integramos con otras empresas con bastante regularidad (AT & T, Cox, Exxon ...) y nunca hemos visto una llamada al servicio web que requiera más de un parámetro.
XML
generalmente tiende a ser camelCased. WSDL
esquema WSDL
y XML
utiliza camelCasing para elementos y atributos, por ejemplo, revisa la sintaxis y el esquema .
Por qué SOAP
se definió de manera diferente, no sé, pero usa PascalCasing para elementos y camelCasing para atributos, verifique aquí .
Del mismo modo, la mayoría de las especificaciones WS*
(tal vez todas) usan PascalCasing para elementos y atributos, mira aquí . XML Schema es agnóstico sobre las convenciones de los tipos que define para XML.
Thomas Erl escribe muchos libros importantes sobre SOA
incluida la "Arquitectura orientada a servicios". En los capítulos 13 y 15 , proporciona una serie de ejemplos del XML de las diversas partes de las transacciones típicas. Define tipos y miembros de objeto en el Esquema XML usando PascalCasing que coincide muy bien con los patrones normales de C # para el nombre de clases y propiedades. Por lo tanto, los valores predeterminados de WCF
ya coinciden estrechamente con los estándares.
En cuanto a la denominación de mensajes reales, algunas convenciones usan camelCasing y otras usan PascalCasing, por lo que mi preferencia es hacer coincidir las necesidades del idioma principal, que en el caso de WCF
es PascalCasing. Y los valores predeterminados de WCF
coinciden con algunos ejemplos de cómo debe escribirse el mensaje de solicitud y respuesta, algunos ejemplos aquí .
Entonces, la única pregunta pendiente es ahora la pregunta básica de cuánto estandarizar en torno al uso de OperationContract
, DataContract
y / o MessageContract
.
Definir DataContract solo cuando uno tiene un tipo complejo (en lenguaje XSD
) tiene sentido, y tiendo a pensar que YAGNI (No lo va a necesitar) como lo señaló Terry es la elección correcta, pero Erl parece sugerir mucho más versión de proceso intensivo así que todavía no estoy seguro de cuál es el mejor enfoque para usar como mi opción predeterminada (la parte principal de la pregunta).