SOA, уровень обслуживания/ответа, принятие и возврат запроса/ответа по массиву или запросов/ответов?

121
12

Мы реализуем "Уровень запроса/ответа" с использованием 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;}
}

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


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


Спасибо

спросил(а) 2011-06-04T13:16:00+04:00 9 лет, 4 месяца назад
1
Решение
158

Прежде всего, массивы добавляют излишнюю сложность. Держите его простым (и) глупым.


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

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


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

ответил(а) 2011-06-13T10:49:00+04:00 9 лет, 4 месяца назад
121

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

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

ответил(а) 2011-06-04T13:23:00+04:00 9 лет, 4 месяца назад
92

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


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


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


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


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


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


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


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


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

ответил(а) 2011-06-13T16:55:00+04:00 9 лет, 4 месяца назад
57

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


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


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

ответил(а) 2011-06-19T23:37:00+04:00 9 лет, 4 месяца назад
57

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


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


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


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


ответил(а) 2011-06-19T18:06:00+04:00 9 лет, 4 месяца назад
57

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


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


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

ответил(а) 2011-06-17T08:05:00+04:00 9 лет, 4 месяца назад
42

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


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


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


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


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

ответил(а) 2011-06-16T18:12:00+04:00 9 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема