SOA, уровень сервиса запросов / ответов, принятие и возврат запроса / ответа против массива или запросов / ответов? - PullRequest
8 голосов
/ 04 июня 2011

Мы реализуем уровень обслуживания запросов / ответов с использованием WCF, где каждый запрос наследуется от базового класса запросов, а каждый ответ наследуется от базового класса ответов.

Служба имеет единственный метод Process, который принимает запрос и возвращает ответ.

// Messages contract
public abstract class Request {}
public abstract class Response {}

// Operation contract
Response Process(Request request);

Однако некоторые члены нашей команды считают, что вместо контракта на эксплуатацию, ожидающего и возвращающего один запрос / ответ, он должен принимать и возвращать массив запросов / ответов.

// Operation contract
Response[] Process(Request[] requests);

Лично я не нахожу это правильным семантически, и в случаях, когда набор связанных запросов требуется обрабатывать сразу (возможно, в пакете), может рассмотреть вопрос о введении сообщений BatchRequest и BatchResponse.

public class BatchRequest : Request
{
    public Request[] Requests {get;set;}
}
public class BatchResponses : Response
{
    public string BatchReference {get; set;} // for example
    public Response[] Responses {get;set;}
}

Мне кажется, что принимать и возвращать массив не правильно, и это, безусловно, шаблон, который я нигде не видел. Есть ли что-то еще не так с этим? Если да, то что это?

Некоторые люди считают, что прием / возврат массивов позволил бы нам не испытывать лишних сложностей при вводе пакетных запросов (как показано выше), и что вы могли бы в любом случае отправить один запрос в массив.

Спасибо

Ответы [ 7 ]

14 голосов
/ 13 июня 2011

Прежде всего, массивы добавляют ненужную сложность. Сохраняйте это простым (и) глупым.

Например. Как следует исправлять ошибки? Если запрос № 1 терпит неудачу, должны ли в любом случае выполняться запросы № 2 и № 3? Как сообщать об ошибках?

Какие проблемы хотят решить ваши коллеги, создавая массивы всех запросов? Если это производительность, то она пахнет преждевременной оптимизацией. Есть несколько других способов улучшить производительность, но ничего не делать, пока это действительно не нужно.

Если нужно освободить клиента, а не ждать результата, переключитесь на асинхронный клиент.

8 голосов
/ 04 июня 2011

Я бы предпочел один запрос и ответ и использовать шаблон команды для пакетирования нескольких действий, которые необходимо выполнить.

Я считаю, что SOA достаточно сложен, и при этом не возникает неожиданных шаблонов. Что произойдет, если часть запросов потерпит неудачу, все ли они откатятся или только неудачные. Аааааа, у меня начинает болеть голова.

4 голосов
/ 13 июня 2011

IMO, ваше решение по разработке / моделированию этих сервисов должно быть полностью основано на сценариях их использования.

Во время моделирования SOA - цель должна заключаться в создании слабосвязанных систем / сервисов - поддерживающих бизнес-область (приложения) в вопросе.

В идеале - ваш сервис должен быть не слишком гранулированным и не слишком сложным.Его повторное использование одинаково важно.По этой самой причине - вам нужно учитывать, что нужно клиентам.

Вот несколько сценариев, в которых может быть полезен любой из них

  1. Информация как услуга

    Доступ к данным (основным данным) через общие службы.- В этом случае на самом деле не имеет смысла обращаться к основным данным в пакетном режиме.

  2. Обновление групповых данных - услуга по миграции пользователей в новый план продаж? (!)

И, я не думаю, что обработка сценариев ошибок с массивами является проблемой - вы действительно не можете обобщить проблему - она ​​очень контекстуальна.Это проектное решение.

Как и в случае [2] выше - вы можете обработать все и вернуть коды ошибок внутри Response [].

1 голос
/ 20 июня 2011

То, что вы рассматриваете, это то, что я называю стратификацией - реализацией простого протокола поверх сложного протокола .Это полностью и совершенно ошибочно.Запрос / ответ, как то, о чем вы думаете, уже существует, и он называется HTTP.

Тем не менее, даже если вы не хотите использовать службы REST, вы не должны делать это таким образом.Если у вас возникают проблемы с вызовом сервисов из-за обновления их контрактов, значит, вы делаете что-то не так.Решение, если вы вынуждены использовать WCF вместо чего-то лучшего, например, nServiceBus, MassTransit или любой другой ESB-инфраструктуры, может выглядеть следующим образом:

  1. Правильно верните контракт службы и создайте сборку, в которой прокси-сервер вызываетк этому договору на обслуживание.Версируйте сборку соответствующим образом и сделайте ее пакетом nuget.
  2. Ссылка на этот пакет nuget из вашего основного проекта.Теперь это больше не меняется.Вам не нужно ничего заново генерировать.
  3. При добавлении символа в интерфейс службы заново создайте сборку и при необходимости ссылайтесь на нее.Храните его в своем репо с исходным кодом.
1 голос
/ 19 июня 2011

Люди, которые предлагают пакетные запросы, всегда думают о производительности интерфейса. И это хорошо. Вопрос должен быть не «Должны ли мы выполнять пакетные запросы или нет?», А скорее «Можем ли мы достичь приемлемой производительности через интерфейс?». Я работал с интерфейсами, которые хорошо работали в локальных сетях (, например, , 10 Мбит Ethernet в офисе), но были медленными по трансатлантическим каналам и просто не работали по транстихоокеанским каналам. Пример, который я имел в виду, рассматривал интерфейс больше как уровень RPC, чем как уровень «бизнес-операций», и это было показано в следах сети.

jgauffin четко ударяет по гвоздю по голове - что означает отказ одного запроса для партии? Являются ли операции упорядоченным списком, чтобы последующие операции не выполнялись? Являются ли они просто набором, сгруппированным для передачи и никак не связанным? Являются ли они составной транзакцией, так что предыдущие успешные операции следует откатить?

Построение API - это искусство, а не наука, и, возможно, черное искусство. Перефразируя правосудие Поттера Стюарта,

"Я не буду сегодня пытаться дальше определить виды материалов, которые я понять, чтобы быть принятым в [хорошее API дизайн]; и, возможно, я никогда не смогу преуспеть в том, чтобы сделать это вразумительно. Но Я знаю это, когда вижу это. "

1 голос
/ 17 июня 2011

Как концепция, пакетный запрос, по-видимому, имеет смысл - в прошлом я вводил такие шаблоны для определенных служб, чтобы уменьшить «болтливость». Кажется, что есть две концепции ответа: понял ли я пакет в целом и каков ответ для каждого участника пакета. Следовательно, это немного больше, чем просто набор ответов.

Я бы также рассмотрел возможность отсроченного исполнения членов партии. Таким образом, первый ответ - «Я понял ваш пакет» с некоторыми другими службами для получения статуса отдельных участников пакета или некоторого механизма доставки асинхронного ответа.

Резюме: вам потребуется индивидуальный запрос / ответ, возможность пакетирования, вероятно, будет полезна и открыта для некоторой степени расширения.

0 голосов
/ 16 июня 2011

По моему опыту, ваш подход, начинающийся с одного шаблона запроса / ответа, а затем позже выставляющий отдельный шаблон BatchRequest / BatchResponse (который содержит массивы запросов / ответов), является лучшим подходом как в краткосрочной, так и в долгосрочной перспективе.для вашего API.

Первоначальный шаблон API, который раскрывается, должен представлять собой один запрос и ответ, просто для того, чтобы иметь простой для понимания интерфейс.Простой интерфейс упрощает изучение шаблонов API (его методов и объектов), что важно для принятия пользователем.Ваши пользователи оценят простоту, когда они сначала изучат API и попытаются просто начать работу с сервисом.Принуждение пользователей к созданию массивов запросов в исходном API не будет оценено, и это усложнит API и приведет к преждевременной оптимизации со стороны ваших коллег.

Однако ваши коллеги правы в том, что будут делать ваши пользователив конечном счете, требуется опция пакетных запросов и ответов, так как они становятся более знакомыми с API.Как вы и предлагали, ваши коллеги действительно лучше справляются с реализацией отдельного шаблона BatchRequest / BatchResponse.Реализация отдельного шаблона BatchRequest / BatchResponse является распространенным явлением, и это может быть сделано способом, который основан на и повторно использует большую часть кода при реализации шаблона запроса / ответа синглтона.Чтобы быть ясным, идея заключается в том, что вы пакетируете свои одиночные запросы от ранее.По моему опыту, идея о том, что ваш API должен запускаться и быть привязанным к шаблону массива запросов / ответов, является ненужной и необоснованной.

Теперь, поскольку я не знаю, каковы варианты использования вашего коллеги, ясобираюсь угадать, почему они хотят получить массивы с самого начала.если ваши коллеги хотят получить массивы запросов, потому что они заинтересованы в выполнении нескольких операций CRUD над несколькими объектами, то решение состоит не в том, чтобы иметь массивы запросов, а в том, чтобы отдельные запросы были привязаны к одному типу операции CRUD, и чтобы запрос принималсямассив объектов для выполнения операции, навалом.Вы не хотите заставлять пользователей выполнять индивидуальный запрос для каждого объекта, поскольку он точно не будет масштабироваться.Пакетирование лучше всего рассматривать как продвинутый метод API, используемый только тогда, когда понятны базовые шаблоны API и когда ваши пользователи хотят масштабировать свои приложения.

Тем не менее сначала представьте один шаблон запроса / ответа.и затем предоставьте необязательный шаблон пакетного запроса / пакетного ответа.Создайте единый шаблон запроса / ответа, помня о том, что в конечном итоге эти запросы будут объединены.

...