Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving settings/variables/permissions in memory instead of looking them up on each API call?

I have an API set up that allows placing orders, looking up product info, reporting, etc. Each API key has specific permissions on which controllers/methods they can or can't access, as well as fields that should be omitted. Unfortunately right now I have this hardcoded in a dictionary class and would like to instead pull these permissions from a database.

The problem is I don't want to call the database to lookup permissions every time a method is called to avoid a performance hit. Is there a way to POST these settings/permissions any time there's a change (using an admin page) and have the API "remember" them in memory in some sort of dictionary? Also when restarting the API I'm guessing these are cleared so I would need a way to pull this information when the API initializes. Not sure what the best way to design this is, any suggestions are helpful thanks.

Edit: I'm avoiding roles because I have hundreds of API keys each with different settings/permissions, which I'm guessing each would need a specific role.

like image 255
Joe Defill Avatar asked Jan 27 '26 03:01

Joe Defill


1 Answers

You can replace your dictionary with MemoryCache. This is a per-instance (instance equating to a single API instantiation using, for example, a Kestrel-based self-hosted setup (likely in the cloud, but not necessarily)).

You can set the expiration time for the cache.

The above behavior would be nondeterministic across multiple instances of instantiations of your API behind a load balancer. That's not necessarily a bad thing. It is common for permissions changes to "take some time to take effect" when they change.

That said, your idea to POST the changes can avoid this latency by directly changing the entries in both the cache and database immediately (cache write-through -- link is Python oriented, but the concepts are sound regardless). This means the next call to the instance gets the new values immediately from memory. This will not survive an "API restart".

Why? Well, an instance has its own memory and that is wiped on a restart. To affect all instantiations of your API, your POST can make the changes against a distributed cache such as Redis, and your database (a centralized, persistent resource) immediately. This is more deterministic and survives restarts. After all, both the distributed cache and the database are persistent stores of data.

If you use distributed caching for this, you just need to pick your caching's back end technology, Redis, DB, or NCache, and configure appropriately.

The key from the API implementation point of view is to try the cache first, and then try the final store... i.e. a normal caching access pattern.

Summarizing, you have two interfaces you can work from

  • IMemoryCache
  • IDistributedCache

and the nuances associated with each.

Finally, as for

I would need a way to pull this information when the API initializes

This is called cache-warming and is quite common and useful. For this I would suggest using a background service, and if you really, really need cache warming to start first, check out Running async tasks on app startup (it's a little dated, but still relevant). Creating this background service would read from the database and write to the cache (in-memory or distributed). In the distributed case, you may have redundant writes to the cache, but that is unlikely to be a real problem).

like image 183
Kit Avatar answered Jan 28 '26 15:01

Kit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!