2012-08-13 4 views
3

Я хочу написать библиотеку, которая свяжется с веб-сервером и выведет данные из него в остальной мир. Веб-сервер не является чем-то особенным, он предоставляет несколько методов REST, в основном GET и POST.Клиент IObservable REST

Поскольку я относительно новичок в реактивных расширениях (но мне это уже нравится), я прошу совета. Я решил, что интерфейсы библиотеки откроют IObservables. Но я не знаю, как именно это реализовать. Я думаю, у меня есть несколько вариантов:

1) Expose IObservable<IEnumerable<T>>. Имеет смысл, служба REST возвращает сразу все запрошенные данные. Пользовательские вызовы Subscribe(), только один IEnumerable нажат, вызывается OnDone. Поэтому Subscribe() нужно будет вызывать несколько раз.

2) Экспозиция IObservable<T>. В некоторых случаях я могу быть хорошим выбором. Подписаться() будет вызываться только один раз, чтобы получить другие данные, были бы методы Refresh() или NextPage() (...), чтобы получить больше данных в потоке. (Тогда вместо IObservable<T> GetResource... это может быть свойством, IObservable<T> Resource { get; }

3) Забудьте Rx, сделать это старомодным способом с помощью событий (неподходящий вещь IMO)

4) каким-либо другим способом?

Любой, у кого есть опыт в этой области? Меня беспокоит Обновление (запрос на новые данные), Пейджинг, объединение результатов и, как правило, хорошая ремонтная конструкция.

Thx за любые советы

ответ

2

Я предложил бы использовать следующий интерфейс:

public interface IRestService 
{ 
    IObservable<T> GetResources<T>(); 
} 

Есть целый ряд причин выбора.

Чтобы разоблачить IObservable<IEnumerable<T>> смеси с Интерактивс реактивов (или наблюдаемых с перечислимыми) и заставят ваши запросы вызвать .ToObservable() или, что еще хуже, .ToEnumerable() построить базовую SelectMany запроса. Лучше для вас лучше сохранить ваши запросы и код подписки красивым.

Теперь вы предложили, чтобы с помощью IObservable<T> вы подписались только один раз, и вам потребуется позвонить Refresh или NextPage, чтобы получить больше данных в потоке. Это не очень хорошая идея. Вы должны думать, что одна подписка вернет все результаты одного вызова REST, а затем вызовет OnComplete. Если вы хотите вызвать новый вызов REST, просто подпишитесь еще раз.

Кроме того, семантика единого вызова подписки четко не выражена в коде. Поэтому вам нужно подумать о поддержке своего кода. Когда вы посмотрите на код в будущем, что вы, вероятно, думаете, что семантика? Я бы предположил, что семантика одной подписки будет сопоставляться с одним вызовом REST. Ваш код мог бы быть более запутанным в противном случае.

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

Я бы также избегал IObservable<T> Resources { get; }, потому что он предлагает какое-то «фиксированное» значение, где вместо этого он более динамичен - другими словами, каждый вызов может дать вам разные значения. Лучше назвать метод GetResources, а не Resources.

Некоторые, нижние строки, у меня бы был IObservable<T>, который абстрагирует один звонок к вашему базовому сервису REST.

+0

Да, но разве идея Rx не имеет единственной подписки и данные передаются вызывающему абоненту? Чтобы подписаться каждый раз, чтобы получить результаты, они не чувствуют себя очень реакционноспособными. –

+0

@ TomášBezouška - Я думаю, вам не хватает точки в отношении способности к работе. Вероятно, у вас будет нажатие кнопки или таймер, который вы хотите инициировать вызовом веб-службы, чтобы просто превратить их в наблюдаемые, а затем создать запрос, который объединяет все вместе любым способом.Важная часть состоит в том, что каждая часть выполняет базовую операцию, и тогда весь запрос может быть мощным. Это имеет смысл? – Enigmativity

+0

Хорошо, и имея метод Refresh() и т. Д., Это сломало бы эту способность, не так ли? Кажется, я понимаю, что для разъяснения. –

0

Вы совмещая две проблемы здесь, которые действительно должны быть рассмотрены отдельно.

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

Что касается первого, то Reactive Extensions не поможет. Ваша озабоченность здесь заключается в том, чтобы получить данные по временному интервалу; он должен быть временным интервалом, потому что, когда вы звоните в службы REST в своем коде, нет обратного вызова, вам нечего зависеть от того, что служба может позвонить.

Если был какой-то обратный вызов в код от внешней службы, то что может быть завернуты в некоторых IObservable<T> implementation, которые вы могли бы подписаться и выполнять свои операции (только переадресация подписки, на самом деле) ,

Единственный способ, которым вы могли бы использовать реактивные расширения для первой проблемы, - это установить таймер с помощью статического Timer method на Observable class.

Для второго беспокойства (после того, как у вас есть ваши данные, и вы хотите, чтобы уведомить абонент), вы абсолютно может и должны использовать IObservable<T> реализации для уведомления абонентов.

В этом случае, я сильно рекомендую вам не попробовать и отклоняться от умысла Subscribe method на интерфейсе IObservable<T>.Вы должны разоблачить метод, который даст вам IObservable<T>, на который может подписаться любой (независимо от того, является ли или нет IObservable<T> до того, как Subscribe вызван до вас) и отказаться от подписки, вызвав Dispose method на реализацию IDisposable interface, возвращенную из вызова до Subscribe.

Таким образом, ваши клиенты могут получить IObservable<T>, подписаться на уведомления, которые они хотят, а затем отказаться от подписки, когда они будут сделаны.

+0

О Rx, не являющемся полезным загружающим материалом - есть одно scenerio, где я нахожу это полезным - сразу получаю сразу несколько ресурсов (с использованием взаимных запросов на отдых), а затем уведомляю о завершении. ForkJoin явный победитель здесь imo. Как вы думаете? –

+0

@ TomášBezouška Я не сказал, что это не полезно скачивать, но, скорее всего, вам лучше разоблачить, что вы загружаете. Большинство сетевых библиотек не возвращают 'IObservable ' реализации, поэтому у вас обычно нет этой роскоши, и вы не указали, что вы делали в своем вопросе. – casperOne

Смежные вопросы