Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds rate limit to APIProvider #227

Merged
merged 5 commits into from
Apr 17, 2023
Merged

Conversation

mathiasemil
Copy link
Contributor

APIProvider now exposes rate limit information from the X-Rate-Limit header field.

public let rateLimitPublisher = PassthroughSubject<RateLimit, Never>()

Rate limits are included in the header for every response and are enforced for all requests using the same API Key.

The documentation defines that the header info includes:

However certain endpoints will also include user-minute-lim and user-minute-rem. I have filed a feedback to ask that this is added to the documentation.
Since this solution does not make assumptions about which entries are included in X-Rate-Limit this should not be an issue.

Usage

let cancellable = apiProvider.rateLimitPublisher.sink { rateLimit in
    if let remaining = rateLimit.entries["user-hour-rem"], let limit = rateLimit.entries["user-hour-lim"] {
        print("Rate limit: \(remaining)/\(limit)")
    }
}

Per endpoint limits
Rate limits apply to all requests, but it appears it is possible for certain endpoints have their own limits. Because of this I have added requestURL to RateLimit so you're able to see rate limits for specific endpoints.

@mathiasemil mathiasemil requested a review from AvdLee as a code owner April 6, 2023 01:03
@SwiftLeeBot
Copy link
Collaborator

SwiftLeeBot commented Apr 6, 2023

Warnings
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'InAppPurchases' is deprecated: Deprecated
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'InAppPurchases' is deprecated: Deprecated
⚠️ 'AppPrice' is deprecated: Deprecated
⚠️ 'AgeRatingDeclaration' is deprecated: Deprecated
⚠️ 'AgeRatingDeclaration' is deprecated: Deprecated
⚠️ 'AppStoreVersionSubmission' is deprecated: Deprecated
⚠️ 'AppStoreVersionSubmission' is deprecated: Deprecated
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'AppPrice' is deprecated: Deprecated
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'InAppPurchases' is deprecated: Deprecated
⚠️ 'AppPrice' is deprecated: Deprecated
⚠️ 'AgeRatingDeclaration' is deprecated: Deprecated
⚠️ 'AppStoreVersionSubmission' is deprecated: Deprecated
⚠️ 'AppStoreVersionSubmission' is deprecated: Deprecated
⚠️ 'Prices' is deprecated: Deprecated
⚠️ 'AvailableTerritories' is deprecated: Deprecated
⚠️ 'AppPrice' is deprecated: Deprecated
Messages
📖 AppStoreConnect-Swift-SDK-Tests: Executed 16 tests (0 failed, 0 retried, 0 skipped) in 0.067 seconds
📖

View more details on Bitrise

Code Coverage Report

Name Coverage

SwiftLint found issues

Severity File Reason
Warning RateLimit.swift:13 Lines should not have trailing whitespace. (trailing_whitespace)
Warning RateLimit.swift:16 Lines should not have trailing whitespace. (trailing_whitespace)
Warning RateLimit.swift:19 Lines should not have trailing whitespace. (trailing_whitespace)
Error RateLimitTests.swift:41 Line should be 160 characters or less: currently 215 characters (line_length)
Warning RateLimitTests.swift:9 Imports should be sorted. (sorted_imports)
Warning RateLimitTests.swift:19 Lines should not have trailing whitespace. (trailing_whitespace)
Warning RateLimitTests.swift:24 Lines should not have trailing whitespace. (trailing_whitespace)
Warning RateLimitTests.swift:30 Lines should not have trailing whitespace. (trailing_whitespace)
Warning RateLimitTests.swift:39 Lines should not have trailing whitespace. (trailing_whitespace)
Warning DefaultRequestExecutor.swift:67 Line should be 140 characters or less: currently 153 characters (line_length)
Warning DefaultRequestExecutor.swift:86 Line should be 140 characters or less: currently 156 characters (line_length)
Warning DefaultRequestExecutor.swift:35 Chained function calls should be either on the same line, or one per line. (multiline_function_chains)
Warning DefaultRequestExecutor.swift:46 Chained function calls should be either on the same line, or one per line. (multiline_function_chains)
Warning DefaultRequestExecutor.swift:60 Use shorthand syntax for optional binding (shorthand_optional_binding)
Warning DefaultRequestExecutor.swift:79 Use shorthand syntax for optional binding (shorthand_optional_binding)
Warning APIProvider.swift:73 Use shorthand syntax for optional binding (shorthand_optional_binding)
Warning APIProvider.swift:9 Imports should be sorted. (sorted_imports)
Warning APIProvider.swift:135 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:241 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:271 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:292 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:309 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:319 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:335 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:348 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:359 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:369 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:377 Lines should not have trailing whitespace. (trailing_whitespace)
Warning APIProvider.swift:103 Parentheses are not needed when declaring closure arguments. (unneeded_parentheses_in_closure_argument)
Warning APIProviderTests.swift:43 Method 'setUp()' should call to super function (overridden_super_call)
Warning APIProviderTests.swift:9 Imports should be sorted. (sorted_imports)

Generated by 🚫 Danger Swift against ae3af97

@mathiasemil
Copy link
Contributor Author

It turns out there was a case sensitivity issue when looking up the rate limit header field name. Apparently Proxyman uppercases all header field names and since the API returns lowercased field names the solution only worked when Proxyman was running🤦‍♂️

I changed the solution to use value(forHTTPHeaderField:) which ensures header field names are case-insensitive.

Copy link
Owner

@AvdLee AvdLee left a comment

Choose a reason for hiding this comment

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

Looks really good, you made it easy to review. Thanks for writing some tests as well!

@AvdLee AvdLee merged commit 1a4bcf2 into AvdLee:master Apr 17, 2023
@mathiasemil mathiasemil deleted the feature/rate-limit2 branch February 23, 2024 10:31
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.

3 participants