Ограничение скорости доступа к API Reddit

Ограничение скорости доступа к API Reddit

1. обзор

В этой быстрой статье мы продолжим улучшатьour small Reddit app наrate limiting the way it has access to the live Reddit API.

Простая идея заключается в том, что мы хотим убедиться, чтоwe don’t hit their API to much - иначе Reddit начнет блокировать запросы. Мы собираемся хорошо использовать GuavaRateLimiter, чтобы добраться туда.

2. ПользовательскийRedditTemplate

Во-первых, давайте создадим шаблон Reddit -a small client for the Reddit API - который объединит все коммуникации низкого уровня в один компонент:

@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(MultiValueMap params) {
        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();
    }
}

Здесь происходит несколько интересных вещей.

Первый -we’re using the Session scope for this bean - просто чтобы каждый пользователь / сеанс в нашем приложении получил свой собственный экземплярRedditTemplate.

Теперь -OAuth2RestTemplate уже поддерживает сохранение учетных данных в рамках сеанса, но мы выходим за рамки этого и делаем фактический сеанс экземпляра bean-компонента ограниченным - так что мы также можемrate limit each user separately.

Это приводит нас к логике фактического ограничения скорости - попросту говоря, мы используем GuavaRateLimiter для получения разрешенияbefore letting the request through and hitting the live 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 доmake sure we’re not blocked by the live API for to much activity.

Это тоже не теоретическая проблема, а на самом деле то, с чем я пару раз сталкивался, используя приложение.

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