Я пишу библиотеку для REST API. Библиотеке придется как можно больше скрыть от пользователя внутреннюю сложность API.Android Retrofit2: как передать параметры запроса запроса на ответ?
Я полагаюсь на retrofit2, сконфигурированный для использования RxJava, чтобы обернуть ответы и GSon для их анализа.
Я использую retrofit для службы REST.
@GET("search")
Observable<SearchResult> search(@Query("q") String query);
@GET("search")
Observable<SearchResult> search(@QueryMap Map<String, String> params);
@GET("search")
Observable<SearchResult> searchNext(@Query("q") String query, @Query("startKey") String startKey);
@GET("search")
Observable<SearchResult> searchNext(@QueryMap Map<String, String> params, @Query("startKey") String startKey);
Поиск REST службы возвращающие JSON
{
"count": 2334,
"nextBatchKey": "SADjdfsahoi023451sadfjlskdfj02134512",
"results": [ .... ]
}
- общее количество результата
- ключ будет использоваться для получения следующей партии из списка
- фактический массив от результатов
Для получения в следующей партии услуга должна быть вызвана снова с теми же параметрами и возвращаемым ключом.
Например, предположим, что делает поиск для q=foo
и limit=20
: The Rest API будет возвращать результаты, соответствующие строки Foo порционный в сегментах 20 результатов каждого. Чтобы получить следующую партию, мне нужно будет создать другой запрос с теми же двумя параметрами: q=foo
и limit=20
, добавив startKey=<the next batch key>
.
Я хочу/должен скрывать от пользователя библиотеки эти внутренние механизмы.
Внутри моей библиотеки я инициализировать переоснащения так:
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient) // added interceptors
.baseUrl(baseUrl) // my base url
.addConverterFactory(GsonConverterFactory.create(gson)) // custom type adapter factory
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
Он генерирует сервис для моего интерфейса и использовать Gson
разобрать ответ оборачивать его RxJava
Observable
.
Тогда я получить услугу:
MyService service = retrofit.create(MyService.class)
Обратите внимание, что я не пишу код этой службы, поскольку Модифицированная работает он генерирует сервис автоматически, используя свой интерфейс (MyService
) аннотаций.
Из библиотеки точки зрения пользователя все это скрыто, он будет просто получить услугу и использовать его как это:
// obtain the service
MyService service = MyLibrarySDK.getService(context);
// perform the search operation
Observable<SearchResult> resultObservable =
service.search(params);
Я хочу, чтобы разработчик, используя свою библиотеку, чтобы иметь возможность получить следующую партию, как это :
// then later result == the SearchResult
Observable<SearchResult> nextBatch =
result.searchNext();
Звонок searchNext()
не принимает никаких параметров. Это означает, что объект SearchResult
, созданный мной в предыдущем вызове, должен знать, какие параметры использовать при использовании метода searchNext(Map parameters, String key)
.
Если пользователь выполняет поисковый вызов с q=foo
, эта информация не будет получена в ответ. И мне это нужно.
С момента создания службы я не знаю, как я могу перехватить параметры метода, переданные с вызовом service.search()
.
Единственная идея, которую я должен был решить эту проблему заключается в использовании OkHttp
перехватчика, разместить параметры запроса карты в ThreadLocal
, а затем использовать пользовательские Gson
TypeAdapter
, чтобы ввести эти параметры в SearchResult
объекта.
Это решение должно технически работать, но я думаю, что это уродливо. Кроме того, перехватчик будет запускаться для любого метода REST API, но мне это нужно только для поисковых запросов.
У вас есть лучшая/креативная/элегантная идея?
Вы бы не получать параметры запроса из модели данных? Вы делаете что-то вроде этого: https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews? – Krishnaraj
@ Кришнарай был моим вопросом плохо написанным? потому что вы спрашиваете, почему я думаю, что вы этого не поняли. Я могу улучшить вопрос, если вы скажете мне, где это путают –
@ Krishnaraj в любом случае, предполагая, что с «моделью данных» вы подразумеваете ответ json для поиска: он содержит только результаты, общее количество и ключ для получения следующей партии. Таким образом, если мне нужно получить следующую партию, мне нужен этот ключ и все параметры, используемые для первого вызова. Я хочу сделать это прозрачным в API-интерфейсе клиента, поэтому мне нужен способ передачи этих параметров. –