1. 概要

この簡単な記事では、ライブRedditAPIへのアクセス方法を制限するレートによって小さなRedditアプリを改善し続けます。

簡単なアイデアは、 APIがあまりヒットしないようにしたいということです。そうしないと、Redditがリクエストのブロックを開始します。 そこに到達するために、Guava RateLimiterをうまく利用します。

2. カスタムRedditTemplate

まず、Redditテンプレート( Reddit API 用の小さなクライアント)を作成しましょう。これにより、すべての低レベルの通信が1つのコンポーネントに統合されます。

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

ここではいくつかの興味深いことが起こっています。

まず、このbean にSessionスコープを使用しています。これは、アプリ内の各ユーザー/セッションが独自のRedditTemplateインスタンスを取得するためです。

現在、 OAuth2RestTemplate は、クレデンシャルセッションのスコープを維持するためのサポートをすでに備えていますが、ここではそれを超えて、実際のbeanインスタンスセッションのスコープを作成します。これにより、各ユーザーのレート制限も可能になります。別途

これにより、実際のレート制限ロジックが導き出されます。簡単に言えば、Guava RateLimiter を使用して、リクエストを通過させてライブAPIにアクセスする前に許可を取得しています。

3. RedditController

次へ– RedditContollerでこの新しいRedditTemplateの使用を開始しましょう–例:

@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によってブロックされないようにしました。

これも理論上の問題ではありませんが、実際には、アプリを使用して何度か遭遇した問題です。

この種の小さな改善が、最終的には成熟した使いやすいアプリケーションにつながるので、この特定のステップに興奮しています。