1. Обзор
В этой краткой статье мы продолжим улучшать наше небольшое приложение Reddit путем ограничения скорости доступа к API live Reddit .
Простая идея заключается в том, что мы хотим убедиться, что мы не сильно ударили по их API – в противном случае Reddit начнет блокировать запросы. Мы собираемся хорошо использовать гуаву RateLimiter , чтобы добраться туда.
2. Пользовательский Шаблон Reddit
Во – первых, давайте создадим шаблон Reddit – небольшой клиент для API Reddit , который объединит все низкоуровневые коммуникации в один компонент:
@Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class RedditTemplate { @Autowired @Qualifier("redditRestTemplate") private OAuth2RestTemplate redditRestTemplate; private RateLimiter rateLimiter; public RedditTemplate() { rateLimiter = RateLimiter.create(1); } public JsonNode getUserInfo() { rateLimiter.acquire(); return redditRestTemplate.getForObject( "https://oauth.reddit.com/api/v1/me", JsonNode.class); } public JsonNode submitPost(MultiValueMapparams) { rateLimiter.acquire(); return redditRestTemplate.postForObject( "https://oauth.reddit.com/api/submit", params, JsonNode.class); } public String needsCaptcha() { rateLimiter.acquire(); return redditRestTemplate.getForObject( "https://oauth.reddit.com/api/needs_captcha.json", String.class); } public String getNewCaptcha() { rateLimiter.acquire(); Map param = new HashMap (); param.put("api_type", "json"); return redditRestTemplate.postForObject( "https://oauth.reddit.com/api/new_captcha", param, String.class, param); } public OAuth2AccessToken getAccessToken() { rateLimiter.acquire(); return redditRestTemplate.getAccessToken(); } }
Здесь происходит несколько интересных вещей.
Во – первых – мы используем область Session для этого компонента – просто для того, чтобы каждый пользователь/сеанс в нашем приложении получил свой собственный экземпляр RedditTemplate .
Теперь – OAuth2RestTemplate уже поддерживает сохранение области сеанса учетных данных, но здесь мы выходим за рамки этого и делаем фактическую область сеанса экземпляра компонента – так что мы также можем ограничить скорость каждого пользователя отдельно .
Что приводит нас к фактической логике ограничения скорости – проще говоря, мы используем Guava RateLimiter для получения разрешения , прежде чем пропустить запрос и обратиться к живому API.
3. RedditController
Далее – давайте начнем использовать этот новый RedditTemplate в RedditContoller – например:
@Controller public class RedditController { @Autowired private RedditTemplate redditTemplate; @Autowired private UserRepository userReopsitory; @RequestMapping("/login") public String redditLogin() { JsonNode node = redditTemplate.getUserInfo(); loadAuthentication(node.get("name").asText(), redditTemplate.getAccessToken()); return "redirect:home.html"; } }
4. Заключение
В этой части тематического исследования мы добавили ограничение скорости в приложение Reddit, чтобы убедиться, что мы не заблокированы live API для большой активности .
Это тоже не теоретическая проблема, но на самом деле то, с чем я сталкивался пару раз, используя приложение.
Именно такие небольшие улучшения в конечном итоге приведут к зрелому и удобному приложению, поэтому я в восторге от этого конкретного шага.