Best format for saving site settings to Mongo?


#1

I would like to save some site settings to the Mongo db through an administrator panel, in order to always have them handy on both client and server. The basic format for settings would be key-value pairs, but this is not the format of collections and documents.

  • Should I make something like a “singleton” collection and just store my key-value pairs in a single document?
  • Or maybe divide the pairs into categories, each with its own document?
  • Or possibly store each pair as a document, like { name: "background", value: "starry pink" }?

It might not be a big impact, but these values need to be retrieved many times all over the site, so I’m thinking about performance as well as practicality. Considerations include whether to use a SimpleSchema and/or AutoForm, and ease of tracking updates.

What will be the easiest, most performant way for me to, at any time, retrieve a setting from Mongo given a key?

P.S. I’m using FastRender to get the settings to the client ASAP.


#2

I have tried out a ‘settings’ collection with only one document and when I first start up the app after a db reset it checks if that single record exists and if not forces you to fill in a ‘default settings’ page that creates the first admin user and a bunch of the settings.

I set up my document with something like:

{ 
  private:  {somePrivateKeyForS3: '1bc9123', otherPrivateUserId: 'abc123' },
  public: {appName: 'my awesome app', ownerEmail: 'admin@domain.com'},
  version: '0.0.1-alpha',
}

Then a null publication that always serves whatever is in public and the root of the document, and private is of course available on the server. This settings document is similar to the settings.json approach (with the private, public vars), so I figured that would make logical sense.

I have tested out using an always available app = {settings: {}} that follows a similar convention but gets extended with the settings collection document, that way I can mix in hard coded settings and user customisable settings reasonably easy.

Only frustrating this is that the subscription always has some delay so in the example, the appName would take a few hundred milliseconds to load in the nav-bar, bit cluncky but works.

I have not settled on a solid approach I am happy with, when I do I might make a package (or see if other packages exist that do this).


#3

I tried out each different solution – not so much as a test, but because I wanted the merits of each in turn – and found that @lbee had the only solution that really works.

My app now uses a config collection with only one document. In the administration panel of the site, I use several autoforms each updating a part of the config doc. Everything works like a charm.


#4

Good to hear it worked out


#5

Hint: Using meteorhacks:fast-render you can set things up such that the data will always be sent along with the initial HTML.

FastRender.onAllRoutes(function () {
    this.subscribe('settings');
});

EDIT: Whoops, this is just what @deb said initially…

Well there you go, now you have the code to see how it’s done exactly!


#6

Great stuff! I will give that a try, thanks.


#7

Using FastRender couldn’t be easier, just make sure your router files are not inside a client or server folder (I’m using lib for my routes) and add the fastrender property.

The only gotcha is forgetting to wrap client specific code inside routes in an if (Meteor.isClient) statement.