Skip to content

Commit 2d3bb6a

Browse files
authored
Merge pull request #20 from RobinTTY/v10.1.0
v10.1.0
2 parents 8c4d580 + 5b7a16e commit 2d3bb6a

File tree

21 files changed

+266
-22
lines changed

21 files changed

+266
-22
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<p align="center">
2-
<img src="docs/static/img/nordigen-api-client-logo.png" width="30%">
2+
<img src="https://raw.githubusercontent.com/RobinTTY/NordigenApiClient/main/docs/static/img/nordigen-api-client-logo.png" width="30%">
33
</p>
44

55
# NordigenApiClient
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: ApiRateLimits
3+
---
4+
5+
The `ApiRateLimits` class represents the rate limits of the GoCardless API.
6+
7+
## Properties
8+
9+
### `RequestLimit` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
10+
11+
Indicates the maximum number of allowed requests within the defined time window. Usually populated in every response.
12+
13+
### `RemainingRequests` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
14+
15+
Indicates the number of remaining requests you can make in the current time window. Usually populated in every response.
16+
17+
### `RemainingSecondsInTimeWindow` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
18+
19+
Indicates the time remaining in the current time window (in seconds). Usually populated in every response.
20+
21+
### `RequestLimitAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
22+
23+
Indicates the maximum number of allowed requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint) within the defined time window. Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).
24+
25+
### `RemainingRequestsAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
26+
27+
Indicates the number of remaining requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint) you can make in the current time window. Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).
28+
29+
### `RemainingSecondsInTimeWindowAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)
30+
31+
Indicates the time remaining in the current time window (in seconds) for requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint). Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).
32+
33+
## Constructor
34+
35+
```csharp
36+
public ApiRateLimits(int requestLimit, int remainingRequests, int remainingTimeInTimeWindow,
37+
int maxAccountRequests, int remainingAccountRequests, int remainingTimeInAccountTimeWindow)
38+
```
39+
40+
### Parameters
41+
42+
#### `requestLimit` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
43+
44+
Indicates the maximum number of allowed requests within the defined time window. Usually populated in every response.
45+
46+
#### `remainingRequests` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
47+
48+
Indicates the number of remaining requests you can make in the current time window. Usually populated in every response.
49+
50+
#### `remainingSecondsInTimeWindow` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
51+
52+
Indicates the time remaining in the current time window (in seconds). Usually populated in every response.
53+
54+
#### `requestLimitAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
55+
56+
Indicates the maximum number of allowed requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint) within the defined time window. Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).
57+
58+
#### `remainingRequestsAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
59+
60+
Indicates the number of remaining requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint) you can make in the current time window. Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).
61+
62+
#### `remainingSecondsInTimeWindowAccountsEndpoint` - [int](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-int32)?
63+
64+
Indicates the time remaining in the current time window (in seconds) for requests to the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint). Only populated in responses from the [AccountsEndpoint](/docs/api-reference/endpoints/accounts-endpoint).

docs/docs/api-reference/responses/nordigen-api-response.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ The result returned by the API. Null if the the HTTP response was not successful
2222

2323
The error returned by the API. Null if the HTTP response was successful.
2424

25+
### `RateLimits` - [ApiRateLimits](/docs/api-reference/responses/api-rate-limits)
26+
27+
The rate limits of the GoCardless API.
28+
2529
## Constructor
2630

2731
```csharp
28-
public NordigenApiResponse(HttpStatusCode statusCode, bool isSuccess, TResult? result, TError? apiError)
32+
public NordigenApiResponse(HttpStatusCode statusCode, bool isSuccess,
33+
TResult? result, TError? apiError, ApiRateLimits rateLimits)
2934
```
3035

3136
### Parameters
@@ -46,6 +51,10 @@ The result returned by the API. Null if the the HTTP response was not successful
4651

4752
The error returned by the API. Null if the HTTP response was successful.
4853

54+
#### `rateLimits` - [ApiRateLimits](/docs/api-reference/responses/api-rate-limits)
55+
56+
The rate limits of the GoCardless API.
57+
4958
## Handling the `NordigenApiResponse` type
5059

5160
To learn more about how to best work with the `NordigenApiResponse` type see the [Handling API responses](/docs/handling-api-responses) guide.

docs/docs/handling-rate-limits.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: Handling Rate Limits
3+
---
4+
5+
The GoCardless API has [rate limits](https://bankaccountdata.zendesk.com/hc/en-gb/articles/11529637772188-Bank-Account-Data-API-Rate-Limits) depending on the endpoint you are using. With most endpoints you shouldn't run into problems since these limits are usually high enough for most uses.
6+
7+
The [Accounts endpoint](/docs/api-reference/endpoints/accounts-endpoint) has very tight limitations though. It currently has a limit of 10 requests a day per access scope. That means 10 requests to each of the [details](/docs/api-reference/endpoints/accounts-endpoint#getaccountdetails), [balances](/docs/api-reference/endpoints/accounts-endpoint#getbalances) and [transactions](/docs/api-reference/endpoints/accounts-endpoint#gettransactions) endpoints. In the future this limit will be lowered to 4 per day (no date on this as of now).
8+
9+
Unsuccessful requests to the API will count towards the general rate limits but not the more stringent limits of the [Accounts endpoint](/docs/api-reference/endpoints/accounts-endpoint). Only successful requests will count towards those.
10+
11+
## Checking API rate limits
12+
13+
You can check the rate limits as well as remaining requests with each request you make to the API. The property [`NordigenApiResponse.RateLimits`](/docs/api-reference/responses/nordigen-api-response#ratelimits---apiratelimits) will hold the returned information about the current API limits.
14+
15+
You can check the limits as follows:
16+
17+
```csharp
18+
// Execute the request you want to make:
19+
var bankAccountDetailsResponse = await client.AccountsEndpoint.GetAccountDetails(accountId);
20+
21+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RequestLimit);
22+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RemainingRequests);
23+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RemainingSecondsInTimeWindow);
24+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RequestLimitAccountsEndpoint);
25+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RemainingRequestsAccountsEndpoint);
26+
Console.WriteLine(bankAccountDetailsResponse.RateLimits.RemainingSecondsInTimeWindowAccountsEndpoint);
27+
```
28+
29+
It's important to handle these limits so your applications user experience isn't degraded. Refreshing data from bank accounts should be handled consciously, so you don't use up all your requests in a short time frame and aren't able to update for the rest of the day.
30+
31+
If you are a company with a contract with GoCardless you can probably get in contact with their team about increasing these limits.

docs/release-notes/v10_0_0.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public async Task<NordigenApiResponse<List<Institution>, BasicResponse>> GetInst
3939

4040
The `TokenPairUpdated` event is now raised whenever the `JsonWebTokenPair` property is successfully updated. Not only when it was automatically updated but also when done so by the user.
4141

42-
**Full Changelog**: [v9.0.0...v10.0.0](https://github.com/RobinTTY/NordigenApiClient/compare/v9.0.0...v10.0.0)
43-
4442
## Other improvements
4543

4644
A full documentation of the library is now available at: [https://robintty.github.io/NordigenApiClient/](https://robintty.github.io/NordigenApiClient/)
45+
46+
**Full Changelog**: [v9.0.0...v10.0.0](https://github.com/RobinTTY/NordigenApiClient/compare/v9.0.0...v10.0.0)

docs/release-notes/v10_1_0.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
slug: v10.1.0
3+
title: v10.1.0
4+
date: 2024-08-19T00:00
5+
---
6+
7+
Added the ability to check newly introduced rate limits in the GoCardless API.
8+
9+
Please refer to the [documentation](/docs/handling-rate-limits) for more information. You can also see the [announcement from GoCardless](https://bankaccountdata.zendesk.com/hc/en-gb/articles/11529584398236-Bank-API-Rate-Limits-and-Rate-Limit-Headers).
10+
11+
**Full Changelog**: [v10.0.0...v10.1.0](https://github.com/RobinTTY/NordigenApiClient/compare/v10.0.0...v10.1.0)

docs/sidebars.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const sidebars: SidebarsConfig = {
66
"quickstart-guide",
77
"handling-api-responses",
88
"handling-authentication-tokens",
9+
"handling-rate-limits",
910
"using-a-different-base-address",
1011
"usage-with-older-dotnet-versions",
1112
"testing",
@@ -38,6 +39,7 @@ const sidebars: SidebarsConfig = {
3839
"api-reference/responses/address",
3940
"api-reference/responses/agreement",
4041
"api-reference/responses/amount-currency-pair",
42+
"api-reference/responses/api-rate-limits",
4143
"api-reference/responses/balance",
4244
"api-reference/responses/balance-type",
4345
"api-reference/responses/bank-account",

src/RobinTTY.NordigenApiClient.Tests/.idea/.idea.RobinTTY.NordigenApiClient.dir/.idea/.gitignore

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RobinTTY.NordigenApiClient.Tests/.idea/.idea.RobinTTY.NordigenApiClient.dir/.idea/.name

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RobinTTY.NordigenApiClient.Tests/.idea/.idea.RobinTTY.NordigenApiClient.dir/.idea/encodings.xml

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RobinTTY.NordigenApiClient.Tests/.idea/.idea.RobinTTY.NordigenApiClient.dir/.idea/indexLayout.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RobinTTY.NordigenApiClient.Tests/.idea/.idea.RobinTTY.NordigenApiClient.dir/.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RobinTTY.NordigenApiClient/Endpoints/AccountsEndpoint.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ private async Task<NordigenApiResponse<List<Balance>, AccountsError>> GetBalance
4646
{
4747
var response = await _nordigenClient.MakeRequest<BalanceJsonWrapper, AccountsError>(
4848
$"{NordigenEndpointUrls.AccountsEndpoint}{accountId}/balances/", HttpMethod.Get, cancellationToken);
49+
4950
return new NordigenApiResponse<List<Balance>, AccountsError>(response.StatusCode, response.IsSuccess,
50-
response.Result?.Balances, response.Error);
51+
response.Result?.Balances, response.Error, response.RateLimits);
5152
}
5253

5354
/// <inheritdoc />
@@ -65,8 +66,9 @@ private async Task<NordigenApiResponse<BankAccountDetails, AccountsError>> GetAc
6566
{
6667
var response = await _nordigenClient.MakeRequest<BankAccountDetailsWrapper, AccountsError>(
6768
$"{NordigenEndpointUrls.AccountsEndpoint}{id}/details/", HttpMethod.Get, cancellationToken);
69+
6870
return new NordigenApiResponse<BankAccountDetails, AccountsError>(response.StatusCode, response.IsSuccess,
69-
response.Result?.Account, response.Error);
71+
response.Result?.Account, response.Error, response.RateLimits);
7072
}
7173

7274
/// <inheritdoc />
@@ -111,8 +113,9 @@ private async Task<NordigenApiResponse<AccountTransactions, AccountsError>> GetT
111113

112114
var response = await _nordigenClient.MakeRequest<AccountTransactionsWrapper, AccountsError>(
113115
$"{NordigenEndpointUrls.AccountsEndpoint}{id}/transactions/", HttpMethod.Get, cancellationToken, query);
116+
114117
return new NordigenApiResponse<AccountTransactions, AccountsError>(response.StatusCode, response.IsSuccess,
115-
response.Result?.Transactions, response.Error);
118+
response.Result?.Transactions, response.Error, response.RateLimits);
116119
}
117120

118121
#if NET6_0_OR_GREATER

src/RobinTTY.NordigenApiClient/Endpoints/InstitutionsEndpoint.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ public async Task<NordigenApiResponse<List<Institution>, BasicResponse>> GetInst
6060
NordigenEndpointUrls.InstitutionsEndpoint, HttpMethod.Get, cancellationToken, query);
6161

6262
return new NordigenApiResponse<List<Institution>, BasicResponse>(response.StatusCode, response.IsSuccess,
63-
response.Result,
64-
response.Error);
63+
response.Result, response.Error, response.RateLimits);
6564
}
6665

6766
/// <inheritdoc />

src/RobinTTY.NordigenApiClient/Models/Errors/CreateAgreementError.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Text.Json.Serialization;
22
using RobinTTY.NordigenApiClient.JsonConverters;
3-
using RobinTTY.NordigenApiClient.Models.Requests;
43
using RobinTTY.NordigenApiClient.Models.Responses;
54

65
namespace RobinTTY.NordigenApiClient.Models.Errors;

src/RobinTTY.NordigenApiClient/Models/Errors/CreateRequisitionError.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Text.Json.Serialization;
22
using RobinTTY.NordigenApiClient.JsonConverters;
3-
using RobinTTY.NordigenApiClient.Models.Requests;
43
using RobinTTY.NordigenApiClient.Models.Responses;
54

65
namespace RobinTTY.NordigenApiClient.Models.Errors;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System.Net.Http.Headers;
2+
using RobinTTY.NordigenApiClient.Endpoints;
3+
4+
namespace RobinTTY.NordigenApiClient.Models.Responses;
5+
6+
/// <summary>
7+
/// The rate limits of the GoCardless API.
8+
/// </summary>
9+
public class ApiRateLimits
10+
{
11+
/// <summary>
12+
/// Indicates the maximum number of allowed requests within the defined time window.
13+
/// Usually populated in every response.
14+
/// </summary>
15+
public int? RequestLimit { get; set; }
16+
/// <summary>
17+
/// Indicates the number of remaining requests you can make in the current time window.
18+
/// Usually populated in every response.
19+
/// </summary>
20+
public int? RemainingRequests { get; set; }
21+
/// <summary>
22+
/// Indicates the time remaining in the current time window (in seconds).
23+
/// Usually populated in every response.
24+
/// </summary>
25+
public int? RemainingSecondsInTimeWindow { get; set; }
26+
/// <summary>
27+
/// Indicates the maximum number of allowed requests to the <see cref="AccountsEndpoint"/>
28+
/// within the defined time window. Only populated in responses from the <see cref="AccountsEndpoint"/>.
29+
/// </summary>
30+
public int? RequestLimitAccountsEndpoint { get; set; }
31+
/// <summary>
32+
/// Indicates the number of remaining requests to the <see cref="AccountsEndpoint"/>
33+
/// you can make in the current time window. Only populated in responses from the <see cref="AccountsEndpoint"/>.
34+
/// </summary>
35+
public int? RemainingRequestsAccountsEndpoint { get; set; }
36+
/// <summary>
37+
/// Indicates the time remaining in the current time window (in seconds) for requests
38+
/// to the <see cref="AccountsEndpoint"/>. Only populated in responses from the <see cref="AccountsEndpoint"/>.
39+
/// </summary>
40+
public int? RemainingSecondsInTimeWindowAccountsEndpoint { get; set; }
41+
42+
/// <summary>
43+
/// Creates a new instance of <see cref="ApiRateLimits" />.
44+
/// </summary>
45+
/// <param name="requestLimit">Indicates the maximum number of allowed requests within the defined time window.</param>
46+
/// <param name="remainingRequests">Indicates the number of remaining requests you can make in the current time window.</param>
47+
/// <param name="remainingSecondsInTimeWindow">Indicates the time remaining in the current time window (in seconds).</param>
48+
/// <param name="requestLimitAccountsEndpoint">Indicates the maximum number of allowed requests to the <see cref="AccountsEndpoint"/>
49+
/// within the defined time window.</param>
50+
/// <param name="remainingRequestsAccountsEndpoint">Indicates the number of remaining requests to the <see cref="AccountsEndpoint"/>
51+
/// you can make in the current time window.</param>
52+
/// <param name="remainingSecondsInTimeWindowAccountsEndpoint">Indicates the time remaining in the current time window (in seconds) for requests
53+
/// to the <see cref="AccountsEndpoint"/>.</param>
54+
public ApiRateLimits(int? requestLimit, int? remainingRequests, int? remainingSecondsInTimeWindow, int? requestLimitAccountsEndpoint,
55+
int? remainingRequestsAccountsEndpoint, int? remainingSecondsInTimeWindowAccountsEndpoint)
56+
{
57+
RequestLimit = requestLimit;
58+
RemainingRequests = remainingRequests;
59+
RemainingSecondsInTimeWindow = remainingSecondsInTimeWindow;
60+
RequestLimitAccountsEndpoint = requestLimitAccountsEndpoint;
61+
RemainingRequestsAccountsEndpoint = remainingRequestsAccountsEndpoint;
62+
RemainingSecondsInTimeWindowAccountsEndpoint = remainingSecondsInTimeWindowAccountsEndpoint;
63+
}
64+
65+
/// <summary>
66+
/// Creates a new instance of <see cref="ApiRateLimits" />.
67+
/// </summary>
68+
/// <param name="headers">The headers of the HTTP response containing the rate limit information.</param>
69+
public ApiRateLimits(HttpHeaders headers)
70+
{
71+
RequestLimit = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_LIMIT");
72+
RemainingRequests = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_REMAINING");
73+
RemainingSecondsInTimeWindow = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_RESET");
74+
RequestLimitAccountsEndpoint = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_ACCOUNT_SUCCESS_LIMIT");
75+
RemainingRequestsAccountsEndpoint = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_ACCOUNT_SUCCESS_REMAINING");
76+
RemainingSecondsInTimeWindowAccountsEndpoint = TryParseApiLimit(headers, "HTTP_X_RATELIMIT_ACCOUNT_SUCCESS_RESET");
77+
}
78+
79+
private static int? TryParseApiLimit(HttpHeaders headers, string headerName)
80+
{
81+
headers.TryGetValues(headerName, out var values);
82+
var firstHeaderValue = values?.FirstOrDefault();
83+
var parseSuccess = int.TryParse(firstHeaderValue, out var limitValue);
84+
85+
return parseSuccess ? limitValue : null;
86+
}
87+
}

0 commit comments

Comments
 (0)