2013-02-15 6 views
10

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

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

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

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

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

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

Благодаря

ответ

14

только с помощью кэширования 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 Не измененная реакция и ваш клиент HTTP будет тянуть ответ из кэша:

304 Not Modified 

Итак, API GitHub делает HTTP-кеширование правильно, и вы должны его использовать. Конечно, вы должны использовать HTTP-клиент, который также поддерживает кеширование HTTP. Лучше всего, если вы получите 304 не измененный ответ - GitHub не уменьшает вашу оставшуюся квоту API-вызовов. См.: http://developer.github.com/v3/#conditional-requests

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

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

+0

Спасибо Иван. Отлично. Использование кеша HTTP также означает, что мне не нужен мой собственный API-интерфейс среднего уровня для кэширования данных в memcached. Таким образом, я могу напрямую обращаться через CORS от клиента (возможно, используя локальное хранилище, если это необходимо). – Ronze

+0

Возможно ли, что не все конечные точки из github возвращают заголовок 'Last-Modified'? Например, вызов в конечную точку вехи не возвращает никакого заголовка 'Last-Modified': curl -i https://api.github.com/repos/p1nox/repos/milestones Но возвращает' ETag', поэтому единственный способ кэшировать такие ресурсы - использовать комбинацию token-etag правильно? – p1nox

+0

@ p1nox Да, это возможно. Если вы прочитаете этот https://developer.github.com/v3/#conditional-requests, вы заметите эту часть: «Большинство ответов возвращают заголовок ETag. Многие ответы также возвращают заголовок Last-Modified». Обратите внимание, что в нем говорится «большинство» и «много», а не «все». –

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