Асинхронный API без сохранения состояния - PullRequest
2 голосов
/ 23 января 2010

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

Чтобы получить информацию, я асинхронно вызываю REST API, используя:

NSURLRequest *request = [NSURLRequest requestWithURL:url
                                      cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                      timeoutInterval:30];

Когда пользователь нажимает на рецепт, вызывается API для получения ингредиентов рецепта. Однако, как только в новом представлении (в котором перечислены ингредиенты) и до получения ответа, пользователь может вернуться и выбрать новый рецепт.

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

Я не уверен, какой подход правильный в этом случае. Я думаю о включении в ответ каждого параметра запроса. Так, если я, например, использую API для поиска определенного термина, мы скажем «foo», я включу термин также в ответ, например:

Запрос:

http://domain.com/api/search?term=foo

Ответ

{
"requestType": "search",
"term": "foo",
"result" : "a foo result"
}

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

¿Есть ли другой способ сделать это?

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

Ответы [ 2 ]

2 голосов
/ 23 января 2010

Одной из возможностей является включение уникального «идентификатора запроса» в запрос и его повторение сервером. Тогда серверу не нужно возвращать все параметры запроса, только идентификатор запроса. Клиент будет генерировать новый идентификатор для каждого запроса, возможно, используя что-то такое же простое, как увеличение целого числа.

Другая возможность - создать «отменяемый асинхронный запрос». Когда вы отправляете запрос, возвращаете объект, который можно использовать для отмены запроса. Если запрос отменен до того, как делегат уволен, убедитесь, что делегат не будет уволен. Когда ответ возвращается на отмененный запрос, просто выбросьте его. Что касается таблицы ингредиентов, то перед тем, как отправлять новый запрос, вы отменяете любой ожидающий запрос (так что у вас может быть не более одного нереализованного запроса за раз).

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

0 голосов
/ 23 января 2010

Типичным подходом здесь является присвоение отдельному уникальному значению («ключевому» значению) для каждого рецепта и отправка его обратно в ответ, как вы и предлагали. Значением ключа может быть имя рецепта, если оно уникальное и короткое, но более распространенной стратегией является использование уникального числа или другого значения, которое не имеет смысла для пользователя, но служит для однозначной идентификации рецепта с течением времени, даже если пример) название меняется. В жаргоне базы данных это разница между ключом business и ключом surrogate . Оба являются уникальными идентификаторами, но бизнес-ключ имеет значение для пользователя (например, имя), тогда как суррогатный ключ - нет. Я рекомендую использовать суррогатный ключ, потому что вы можете сделать его коротким, и его никогда не нужно будет менять, потому что пользователь не заботится об этом.

Обратите внимание, что если вы принимаете ключ обратно в качестве параметра в любом из вызовов веб-службы, вы должны проверить его (или зашифровать, если это касается безопасности), поскольку вы никогда не знаете, будет ли клиент вмешиваться в него. 1007 *

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...