Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is for the take home assignment for staff engineer position in Crexi.
I thought it would be nice to kinda show end to end work including example endpoints (controllers) as actual API resource examples. So some works were done to present Swagger as UI to play with.
launchSettings.json is provided to run the solution, choose profile "RateLimiter" to run and play.
Swagger UI will appear at: http://localhost:5000/swagger/index.html
Since there were some mock data seeded as InMemoryDatabase injected in Program.cs to simulate data available, in the swagger Custom-Header below can be used to test:
{ "Id" : "296035ED-532E-46C9-8172-60806CC86B50", "Region": "US" }
In actual production, this can be replaced to actual database or Redis, etc.
There were Users data and Properties data resources to represent different API resources and mock data were seeded as InMemoryDatabase to play with.
However all the interesting stuff is in the Services.Common project considering this work would be cross cutting concern, to be reused and exploited in any endpoints and API projects. So maybe if this is actually delivered in production, maybe provided as infrastructure layer work, either as common library (nuget pkg) or maybe gateway implmentation before actually reaching each endpoint.
This work considers dynamic loading of configurations. It's done via json format, which in production could be retrieved in database or redis, etc.
However for simplisity, there is 'rateLimitConfig.json' seeded in this project, which will represent per region, per resource configurations of rules.
This configurations are loaded via IRuleConfigLoader with RuleCofigLoader, which is backgroundservice and currently set to refresh every 24 hours considering rule configurations wouldn't change frequently.
How the rules results aggregated are determined by IRateLimiter, with current example of DynamicRateLimiter, which applies condition of all rules required should pass to let the request reach the API resource.
IRateLimitFactory will instantantiate each required rule, which will contain cache getting updated per client states to calculate rule result for each client.
Each rule implements IRateLimitRule to be compliant to aggregated abstracted IsRequestAllowed call.
Middleware was used to check the rules before letting request reach each API endpoint resource.