Limiter l’accès à l’API Reddit

Limiter l'accès à l'API Reddit

1. Vue d'ensemble

Dans cet article rapide, nous allons continuer à améliorerour small Reddit app derate limiting the way it has access to the live Reddit API.

L'idée simple est que nous voulons nous assurer quewe don’t hit their API to much - sinon Reddit commencera à bloquer les requêtes. Nous allons faire bon usage des GuavaRateLimiter pour y arriver.

2. UnRedditTemplate personnalisé

Commençons par créer un modèle Reddit -a small client for the Reddit API - qui regroupera toutes les communications de bas niveau en un seul composant:

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

Quelques choses intéressantes se passent ici.

Tout d'abord -we’re using the Session scope for this bean - simplement pour que chaque utilisateur / session de notre application obtienne sa propre instance deRedditTemplate.

Maintenant - leOAuth2RestTemplate prend déjà en charge le maintien de la portée de la session des identifiants, mais nous allons au-delà de cela ici et rendons la session de l'instance de bean réelle ciblée - afin que nous puissions égalementrate limit each user separately.

Ce qui nous amène à la logique de limitation de débit réelle - en termes simples, nous utilisons lesRateLimitergoyaves pour acquérir un permisbefore letting the request through and hitting the live API.

3. LesRedditController

Ensuite, commençons à utiliser ce nouveauRedditTemplate dans lesRedditContoller - par exemple:

@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. Conclusion

Dans cette partie de l'étude de cas, nous avons ajouté la limitation de débit à l'application Reddit, àmake sure we’re not blocked by the live API for to much activity.

Ce n’est pas non plus un problème théorique - mais en fait quelque chose que j’ai rencontré à plusieurs reprises en utilisant l’application.

Ce sont ces types de petites améliorations qui finiront par aboutir à une application mature et utilisable. Je suis donc enthousiasmé par cette étape particulière.