Какова наилучшая практика при проектировании веб-сервисов SOA WCF?
С учетом рабочего договора, например:
[OperationContract]
void Operation(string param1, string param2, int param3);
Это может быть изменено на:
[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);
Одна вещь, которая мне нравится в MessageContract, заключается в том, что я получаю немного более явный контроль над форматом сообщения SOAP.
Аналогично, я мог бы написать почти тот же код, но использовать 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);
Мне нравится в DataContract, что я могу определить IsRequired, Order и Name.
Сегодня я ожидаю, что единственным клиентом будет WCF-клиент. Тем не менее, я хочу сначала разработать контракт и придерживаться практики SOA как можно больше. Вместо того, чтобы WCF диктует мои SOAP, WSDL и XSD, я хочу, чтобы XML определял уровень WCF, но используйте WCF для его создания, чтобы не добавлять какую-либо обработку пользовательских сообщений в WCF. Я хочу следовать наиболее распространенным соглашениям XML SOA, которые, я считаю, вероятно, являются тегами, начинающимися в нижнем регистре - я прав? И я хочу быть максимально толерантным к версии.
Можно ли всегда создавать сообщения "Запрос" и "Ответ" как это? Какой из трех форматов способствует лучшей практике SOA? Должен ли я идти еще дальше и определять как DataContract, так и MessageContract, в которых MessageContract содержит только DataContract? Или я должен использовать DataContracts когда-либо, если я действительно раскрываю новый тип (т.е. Не создавайте типы сообщений в качестве контейнеров)?
Загруженный набор вопросов, которые я знаю, но я пытаюсь понять его суть, и я не уверен, что разделение вопросов дает достаточный контекст для получения ответа, который я ищу.
Ответы
Ответ 1
XML
обычно имеет тенденцию быть camelCased. WSDL
и XML
Схема использует camelCasing для обоих элементов и атрибутов, например, проверьте syntax и schema.
Почему SOAP
был определен по-разному, я не знаю, но он использует PascalCasing для элементов и camelCasing для атрибутов, проверьте здесь.
Similary, большинство спецификаций WS*
(возможно, все) используют PascalCasing для элементов и атрибутов, см. здесь. XML Schema агностически относится к соглашениям типов, которые он определяет для XML.
Томас Эрл пишет много важных книг по SOA
включая "сервис-ориентированную архитектуру". В главах 13 и 15 он содержит ряд примеров XML различных частей типичных транзакций. Он определяет типы и элементы объекта в XML-схеме с использованием PascalCasing, который хорошо соответствует нормальным образцам С# для присвоения классов и свойств. Таким образом, WCF
значения по умолчанию уже соответствуют стандартам.
Что касается фактического именования сообщений, некоторые соглашения используют camelCasing, а другие используют PascalCasing, поэтому я предпочитаю соответствовать основным потребностям языка, который в случае WCF
- PascalCasing. И WCF
defaults соответствуют некоторым примерам того, как должно быть написано сообщение о запросе и ответе, несколько примеров здесь.
Таким образом, единственным нерешенным вопросом является теперь основной вопрос о том, насколько стандартизировать использование OperationContract
, DataContract
и/или MessageContract
.
Определение DataContract только тогда, когда у вас сложный тип (в XSD
parlance) имеет смысл, и я склонен думать, что YAGNI (вам это не понадобится), как указал Терри, является правильным выбором, но Erl кажется, предлагает гораздо более интенсивную обработку, поэтому я все еще не уверен, что лучший подход к использованию в качестве моего выбора по умолчанию (основная часть вопроса).
Ответ 2
всегда всегда лучше не иметь нескольких параметров в контракте операции, всегда иметь тип, который обертывает все необходимые параметры, это поможет в долгосрочной перспективе. Ваши существующие клиенты не сломаются при добавлении нового необязательного параметра.
Я работаю в команде по интеграции бизнеса, где мы регулярно проводим интеграцию с другими компаниями (AT & T, Cox, Exxon...) и никогда не видели вызова веб-службы, в котором принималось больше одного параметра.
Ответ 3
Я думаю, что это честно зависит от сценария. Если вы просто обмениваетесь простыми типами [т. строка], OperationContract, безусловно, приемлемо.
Вы должны использовать MessageContract, если хотите изменить формат сообщения, и DataContract следует использовать, если вы хотите выразить сложный тип, например адрес.
Ответ 4
YAGNI здесь.
Я говорю, не делайте этого, слишком задумываясь о будущем. WCF уже хорошо подходит для SOA. Я говорю, в общем, придерживаюсь значений по умолчанию и будьте осторожны с привязкой, пока у вас не возникнет особая необходимость сделать что-то сложное.