Application config in a single-row table

Here’s the scenario: I am building a fairly straightforward web application that grabs some data from an external API and displays it in various ways on a dashboard. Essential to the process of making this particular data retrieval possible is the existence of an api key. This single key unlocks the API and all of its captivating curiosities for my app.

Other than actually accessing this data, one of my additional requirements was the ability to conveniently change the API key whenever I wanted, without having to dive into the application’s codebase. How can I do this?

I’m using Ruby on Rails, but this should prove to be fairly inconsequential. Sure, there are ways to handily and safely store application-wide configuration (like API keys) in Rails specifically, such as slotting them directly into the codebase like this:

# config/environments/production.rb
config.mailchimp_api_key = “ABCDEF”

Or I could use encrypted Rails secrets, and store something like an api key in the config/secrets.yml file, which could then be accessed like this:

Rails.application.credentials.dig(:facebook, :api_key)

The problem with both of these solutions is that they are not dynamic - if I want to update the key I’ve got to manually go into the codebase to change it, test it, then re-deploy the app. It’s just a bit of a faff, and I wanted to eliminate the dependence on somebody with access to, and knowledge of, the app’s codebase.

So, I decided to store the key in a database table - truly groundbreaking stuff. Let’s dig into why this simple solution works really well, and how you can go about implementing it.

I’ve gone with the Single Row Table (SRT). It’s relatively self-explanatory: it’s a table with a single row in it. In my case, this table is called app_settings, and its columns store an assortment of application-wide configuration, including my all-important API key. I can now perform ordinary read/write operations as I would with any other table. However, the difference here being that there’s only ever one row (or record) in the table itself. It might look like this:

| id | encrypted_api_key | encrypted_api_key_iv  | ...  |
| -- |------------------:| ---------------------:| ----:|
| 1  | asD2-f21Fa-126d-a | dbRs23Gjg82dsGDsF     | ...  |

Carrying this out in Rails is very straightforward - I can’t see how it could be much more complicated in any other web framework:

1. Using the attr_encrypted gem I followed the documentation’s short instructions to create a model called AppSetting (with a corresponding migration to create the app_settings table), along with an encrypted attribute/column for my API key.

2. To ensure I only ever create and use a single record on this table, I needed an interface that only performs queries on this  particular row. I added this class method to the AppSetting model, which calls Active Record's handy 'first_or_create' method:

def self.current
   first_or_create
end

3. From this point onwards, any time I use the AppSetting model, I do so in conjunction with the current class method:

Services::Api::Request.call(api_key: AppSetting.current.api_key)

Importantly, I now have the means to easily update the api key through the app’s user interface using any old form.

There’s every chance you’re reading this trying to determine whether or not a single-row table just sounds a bit strange. I also sat there similarly deliberating and searching for what I hoped might be a “cleaner” way of doing it. I came across one other popular and viable solution: the Entity-Attribute-Value (EAV) table (also sometimes described as the Name-Value-Pair table).

EAV works very simply by defining a row per configuration value: you would create a table with a column for a setting name and a column for a setting value. In the context of my requirements, the table might look like this:

| config_option        | value              |
| --------------------:| ------------------:|
| encrypted_api_key    | asD2-f21Fa-126d-a  |
| encrypted_api_key_iv | h4fhSDFDFasQ2      |

EAV’s appeal is obvious: you access a table in which each of your config options has its own row in the format of the familiar-looking key value pair. My decision to roll a Single Row Table however was very simply based on the fact that the general sentiment on developer forums seemed to favour SRT over EAV. I seized the opportunity to dip into the analog tool-belt and jot down a pros/cons list. I’ve shared this below to help you pick or plan your response to the rare-sighted “editable application-wide config” conundrum.

Single Row Table Pros

Single Row Table Cons

Entity-Attribute-Value Pros

Entity-Attribute-Value Cons

| config_option        | string_value       |  int_value    |
| --------------------:| ------------------:| -------------:|
| encrypted_api_key    | asD2-f21Fa-a26d-a  | NULL          |
| refresh_seconds      | NULL               | 20            |

In reality, this problem likely won’t surface very often for you. That said, it’s certainly a talking point for anyone looking to add in some editable application-wide configuration for their app(s). The take away and TL;DR here is that SRT and EAV are seemingly the most popular solutions.