Skip to content

feat(school): 학교 클라이언트에 rate limiter 적용#281

Merged
huhdy32 merged 3 commits intodevelopfrom
feat/school-rate-limiter
Jan 9, 2026
Merged

feat(school): 학교 클라이언트에 rate limiter 적용#281
huhdy32 merged 3 commits intodevelopfrom
feat/school-rate-limiter

Conversation

@huhdy32
Copy link
Collaborator

@huhdy32 huhdy32 commented Jan 9, 2026

Summary by CodeRabbit

  • New Features
    • Added rate limiting for school lookup operations and built-in fallback handling to keep responses stable during high load.
  • Tests
    • Updated test configuration to validate rate-limiting behavior under constrained conditions.
  • Chores
    • Added runtime support for resilience patterns and AOP to enable rate limiting and fallback mechanisms.

✏️ Tip: You can customize this high-level summary in your review settings.

@huhdy32 huhdy32 self-assigned this Jan 9, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 9, 2026

📝 Walkthrough

Walkthrough

Adds Resilience4j rate limiting to SchoolClient by annotating three deprecated methods with @RateLimiter and providing fallback methods; enables Lombok logging; updates test properties for rate limiter; adds Resilience4j and AOP dependencies to the build. (48 words)

Changes

Cohort / File(s) Summary
SchoolClient — rate limiter & fallbacks
client/external/mathrank-school/src/main/java/kr/co/mathrank/client/external/school/SchoolClient.java
Adds @RateLimiter(name="neiceApi", fallbackMethod=...) to getSchool, getSchools, getSchoolsByCityName; introduces private fallback methods returning default empty/null responses and logging via Lombok @Slf4j; adds Resilience4j and Lombok logging imports.
Test — rate limiter properties
client/external/mathrank-school/src/test/java/kr/co/mathrank/client/external/school/SchoolClientTest.java
Adds Resilience4j rate limiter properties to @SpringBootTest (limit-refresh-period, limit-for-period, timeout-duration) for tests.
Build — dependencies
client/external/mathrank-school/build.gradle
Adds io.github.resilience4j:resilience4j-spring-boot3:2.2.0 and org.springframework.boot:spring-boot-starter-aop dependencies to enable Resilience4j integration and AOP support.

Sequence Diagram(s)

sequenceDiagram
    actor Caller
    participant SchoolClient
    participant RateLimiterAspect as RateLimiter (Resilience4j)
    participant ExternalAPI

    Caller->>SchoolClient: call getSchools(...)
    SchoolClient->>RateLimiterAspect: aspect intercepts call
    alt within limit
        RateLimiterAspect->>SchoolClient: proceed
        SchoolClient->>ExternalAPI: perform request
        ExternalAPI-->>SchoolClient: response
        SchoolClient-->>Caller: return response
    else limit exceeded or timeout
        RateLimiterAspect-->>SchoolClient: trigger fallback
        SchoolClient-->>Caller: return fallback (empty/null) and log warning
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇
I hopped to guard the schoolroom gate,
Rate limits set to calm the rate,
Three methods wrapped in gentle care,
Fallbacks ready when calls despair,
Logging whispers, all is fair.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: applying rate limiting to the school client using Resilience4j, which aligns with all modifications across the three changed files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @huhdy32, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 외부 학교 클라이언트에 Rate Limiter를 적용하여 외부 API 호출을 제어하고 과도한 요청으로 인한 서비스 장애를 방지하는 것을 목표로 합니다. Resilience4j 라이브러리를 활용하여 특정 메서드에 Rate Limiter를 설정하고, 제한을 초과할 경우 정의된 폴백 메서드를 통해 안정적으로 처리하도록 구현되었습니다.

Highlights

  • Resilience4j Rate Limiter 적용: 외부 학교 클라이언트(SchoolClient)에 io.github.resilience4j.ratelimiter.annotation.RateLimiter 어노테이션이 추가되어 Rate Limiting 기능이 도입되었습니다.
  • 로깅 기능 추가: SchoolClient 클래스에 lombok.extern.slf4j.Slf4j 어노테이션이 추가되어 로깅 기능을 사용할 수 있게 되었습니다.
  • 메서드별 Rate Limiter 및 폴백 구현: getSchool, getSchools, getSchoolsByCityName 메서드에 @RateLimiter(name = "neiceApi", fallbackMethod = "...") 어노테이션이 적용되었으며, 각 메서드에 대한 폴백 메서드(fallBackSchoolInfo, fallBackGetSchools, fallBackGetSchoolsByCityName)가 구현되어 Rate Limiting 발생 시 안정적으로 처리합니다.
  • 테스트 환경 설정 추가: SchoolClientTest.java 파일에 neiceApi Rate Limiter에 대한 Resilience4j 설정 속성(limit-refresh-period, limit-for-period, timeout-duration)이 추가되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 외부 NEIS API에 대한 과도한 호출을 방지하기 위해 Resilience4j를 사용하여 SchoolClient에 rate limiter를 도입합니다. Rate limit이 적용된 함수들에 대해 폴백 메서드가 추가되었으며, 이 메서드들은 rate limit을 초과했을 때 경고를 로깅하고 기본 응답을 반환합니다. 변경 사항은 논리적이며 rate limiting 패턴을 올바르게 구현했습니다. 제 리뷰에는 새로운 메서드의 파라미터에 final을 사용하여 코드 일관성을 개선하고, 폴백 응답을 생성할 때 null 사용을 피하는 제안이 포함되어 있습니다. 또한 rate limiter와 폴백 메커니즘이 예상대로 작동하는지 확인하기 위한 테스트 케이스를 추가할 것을 권장합니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In
@client/external/mathrank-school/src/main/java/kr/co/mathrank/client/external/school/SchoolClient.java:
- Line 45: Update all production call sites to use the public wrapper methods on
SchoolClient (getSchoolResponse and getSchoolsResponse) instead of directly
invoking the deprecated, rate-limited methods (getSchool and getSchools) so the
centralized error handling in RestClientResponseDecorator (which decorates the
deprecated methods) is applied; change callers in ProblemReadQueryService,
SchoolLocationManager, RankReadController, MemberDetailQueryController, and
SchoolQueryService to call getSchoolResponse/getSchoolsResponse, and after
verifying all callers use the wrappers you may move the @RateLimiter annotation
from the deprecated methods into the wrapper methods if desired.

In
@client/external/mathrank-school/src/test/java/kr/co/mathrank/client/external/school/SchoolClientTest.java:
- Around line 16-18: Add the resilience4j rate limiter settings used in tests
into production properties so SchoolClient uses the same limits in runtime:
create or update the module's production application.properties and add the
three keys resilience4j.ratelimiter.instances.neiceApi.limit-refresh-period=1s,
resilience4j.ratelimiter.instances.neiceApi.limit-for-period=100, and
resilience4j.ratelimiter.instances.neiceApi.timeout-duration=1s; keep the
instance name neiceApi (it is referenced by the @RateLimiter annotations in
SchoolClient and used by MemberDetailQueryController and RankReadController).
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 239a084 and 631f886.

📒 Files selected for processing (2)
  • client/external/mathrank-school/src/main/java/kr/co/mathrank/client/external/school/SchoolClient.java
  • client/external/mathrank-school/src/test/java/kr/co/mathrank/client/external/school/SchoolClientTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
client/external/mathrank-school/src/main/java/kr/co/mathrank/client/external/school/SchoolClient.java (2)
client/mathrank-client-config/src/main/java/kr/co/mathrank/client/config/RestClientResponseDecorator.java (1)
  • Slf4j (12-27)
domain/mathrank-problem-domain/src/main/java/kr/co/mathrank/domain/problem/service/SchoolLocationManager.java (1)
  • Slf4j (14-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (2)
client/external/mathrank-school/src/main/java/kr/co/mathrank/client/external/school/SchoolClient.java (2)

14-14: LGTM: Required imports and logging added correctly.

The imports for @RateLimiter and @Slf4j are necessary for the rate limiting functionality and fallback logging.

Also applies to: 23-23, 25-25


89-92: Remove this review comment — the concern is unfounded.

SchoolResponse.getSchoolInfo() explicitly checks for null at line 16 and safely returns an empty list when schoolInfo is null. No NullPointerException will occur when callers invoke getSchoolInfo() on the fallback response.

Likely an incorrect or invalid review comment.

@math-len math-len deleted a comment from coderabbitai bot Jan 9, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
client/external/mathrank-school/build.gradle (1)

3-4: Version 2.2.0 is stable and secure; consider upgrading to 2.3.0 if you want to stay current.

The dependencies are appropriate for implementing rate limiting with Resilience4j annotations. Version 2.2.0 (released Sep 2024) has no known security vulnerabilities. However, 2.3.0 is now available; upgrading is optional but recommended if you want to track the latest stable release.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 631f886 and ae02b31.

📒 Files selected for processing (1)
  • client/external/mathrank-school/build.gradle
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test

@huhdy32 huhdy32 enabled auto-merge (squash) January 9, 2026 09:32
@huhdy32 huhdy32 merged commit b2b946c into develop Jan 9, 2026
2 checks passed
@huhdy32 huhdy32 deleted the feat/school-rate-limiter branch January 9, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant