Рубрики
Без рубрики

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

Как ввести ограничение скорости в приложение при использовании внешнего API.

Автор оригинала: baeldung.

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(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();
    }
}

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

Во – первых – мы используем область 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 для большой активности .

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

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