Кеширование вызовов API Github

У меня общий вопрос, связанный с кешированием вызовов API, в данном случае вызовов API Github.

Допустим, у меня есть страница в моем приложении, которая показывает имена файлов репо и содержимое README. Это означает, что мне нужно будет сделать несколько вызовов API, чтобы получить это.

Теперь предположим, что я хочу добавить что-то вроде memcached между ними, поэтому я не буду повторять эти вызовы снова и снова, если мне это не нужно.

Как бы вы обычно это делали? Если я не включу веб-перехватчик на Github, я не смогу узнать, истечет ли срок действия кеша. Я всегда мог сделать один вызов, чтобы получить текущий sha HEAD, и, если он не изменился, вместо этого использовать кеш. Но это на уровне репо, а не на уровне файлов.

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

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

Спасибо


person Ronze    schedule 15.02.2013    source источник


Ответы (1)


Достаточно ли для вашего случая использования просто HTTP-кеширования? Цель HTTP-кеширования не только в том, чтобы предоставить способ не делать запросы, если у вас уже есть свежий ответ, но и в том, чтобы вы могли быстро проверить, является ли ответ, который у вас уже есть в кеше, действительным (без отправки сервером полного ответа). ответ еще раз, если он свежий).

Глядя на ответы API GitHub, я вижу, что GitHub правильно устанавливает соответствующие заголовки HTTP (ETag, Last-modified, Cache-control).

Итак, вы просто выполняете GET, например. для:

GET https://api.github.com/users/izuzak/repos

и это возвращается:

200 OK
...
ETag:"df739f00c5053d12ef3c625ad6b0fd08"
Last-Modified:Thu, 14 Feb 2013 22:31:14 GMT
...

В следующий раз вы выполняете GET для того же ресурса, но также предоставляете соответствующие заголовки HTTP-кеширования, так что на самом деле это условный GET:

GET https://api.github.com/users/izuzak/repos
...
If-Modified-Since:Thu, 14 Feb 2013 22:31:14 GMT
If-None-Match:"df739f00c5053d12ef3c625ad6b0fd08"
...

И о чудо - сервер возвращает ответ 304 Not modified, и ваш HTTP-клиент вытащит ответ из своего кеша:

304 Not Modified

Итак, GitHub API правильно выполняет кеширование HTTP, и вы должны его использовать. Конечно, вы должны использовать HTTP-клиент, который также поддерживает HTTP-кеширование. Лучше всего то, что если вы получите ответ 304 Not modified - GitHub не уменьшит вашу оставшуюся квоту вызовов API. См. https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests

GitHub API также устанавливает заголовок Cache-Control: private, max-age=60, поэтому у вас есть 60 секунд свежести - это означает, что запросы одного и того же ресурса, сделанные с интервалом менее 60 секунд, даже не будут отправлены на сервер.

Ваше рассуждение об использовании одного условного запроса GET к ресурсу, который обязательно изменится, если что-то в репо изменилось (например, ресурс, показывающий sha HEAD), звучит разумно - поскольку, если этот ресурс не изменился, вы не Нет необходимости проверять отдельные файлы, поскольку они точно не изменились.

person Ivan Zuzak    schedule 15.02.2013
comment
Спасибо, Иван. Отлично. Использование HTTP-кеша также означает, что мне не нужен мой собственный API-маршрут среднего уровня для кеширования вещей в memcached. Таким образом, я могу перейти напрямую через CORS от клиента (возможно, используя локальное хранилище, если это когда-либо понадобится). - person Ronze; 15.02.2013
comment
Возможно ли, что не все конечные точки из github возвращают заголовок Last-Modified? Например, вызов конечной точки вех не возвращает заголовок Last-Modified: curl -i api. github.com/repos/p1nox/repos/milestones Но возвращает ли ETag, поэтому единственный способ кэшировать такие ресурсы - использовать комбинацию токен-etag, верно? - person p1nox; 18.02.2016
comment
@ p1nox Да, это возможно. Если вы прочитали этот developer.github.com/v3/#conditional-requests, вы заметите эту часть: большинство ответов возвращают заголовок ETag. Многие ответы также возвращают заголовок Last-Modified. Заметьте, что здесь сказано большинство и многие, а не все. - person Ivan Zuzak; 19.02.2016
comment
Да, я видел это, но это несколько двусмысленно, я надеялся, что мое предположение после прочтения было неправдой: P. Спасибо @IvanZuzak. - person p1nox; 19.02.2016