Перейти к основному содержимому

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

· 2 мин. чтения

1. Обзор

В этой быстрой статье мы продолжим улучшать наше небольшое приложение Reddit , ограничивая скорость доступа к API Reddit в реальном времени .

Простая идея заключается в том, что мы хотим убедиться, что мы не сильно ударим по их API, иначе Reddit начнет блокировать запросы. Мы собираемся хорошо использовать Guava RateLimiter , чтобы добраться туда.

2. Пользовательский шаблон Reddit

Во-первых, давайте создадим шаблон Reddit — небольшой клиент для 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<String, String> 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<String, String> param = new HashMap<String, String>();
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();
}
}

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

Во- первых , мы используем область сеанса для этого компонента — просто для того, чтобы каждый пользователь/сеанс в нашем приложении получил свой собственный экземпляр RedditTemplate .

Теперь OAuth2RestTemplate уже поддерживает сохранение области сеанса учетных данных, но здесь мы выходим за рамки этого и делаем фактический сеанс сеанса экземпляра компонента ограниченным, чтобы мы также могли ограничивать скорость для каждого пользователя отдельно .

Что приводит нас к фактической логике ограничения скорости — проще говоря, мы используем Guava RateLimiter для получения разрешения, прежде чем пропустить запрос и попасть в живой API.

3. Контроллер Reddit

Далее — давайте начнем использовать этот новый 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, чтобы убедиться, что живой API не блокирует нас из-за чрезмерной активности .

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

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