静态字符串映射器的Node JS最佳实践



我正在运行一个Node JS应用程序(Sails JS,但不应该重要)和MongoDB(也不应该重要)。

我有一个数据库模型,WebApp保存了它的许多实例。为简单起见,让我们以UserActivityHistory模型为例(该示例不是我的实际情况,因此不用考虑逻辑)。

模型的成员之一是"ActivityType",它可以是中长文本,但可以从静态集合中选择。例如:

  • ActivityType可以是下列类型之一:
    1. "用户添加新帐户".
    2. "User changed account password".
因此,假设我要保存数千个实例,我更喜欢保存活动类型标识符/代码以提高内存性能。例如:

WebApp不应该保存"User added a new account",而应该保存" unc "。

当用户想要查看"UserActivityHistory"时,我想要有一个静态映射器(可能是全局变量?),这是某种字典,如下所示:

  • ["UNAC"]="用户添加了一个新帐户"
  • ["UCAP"] = "User changed account password"

这意味着,我接收活动的代码并返回静态字典中的文本,该字典保存在运行应用程序的服务器内存中。

实现这种映射的最有效的方法和最佳实践是什么?

我想到的方法:

1) 全局变量:保存全局字典并通过API调用从中添加/删除值。我不确定这是不是一个明智的想法,我仍然不明白为什么不,但我的内心深处仍然有东西告诉我不要相信全局变量。

2) 在另一个数据库中保存映射器:这需要为每组活动再次调用数据库。(如果我一次加载许多活动,对我来说似乎不那么重,但仍然可能有一个更好的解决方案)。

  • 请注意,我想添加动态活动,所以有一个开关情况下的功能不是一个适当的解决方案。

如果你想避免每次字符串更改时都必须重新部署应用程序,那么我建议你考虑从一些持久化存储(例如外部文件/DB)中提取这些。

无论你选择哪一个,给定它们是应用程序设置,你会在应用程序启动或第一次访问时拉出它们。这将使你能够灵活地更改它们-与应用程序(或者甚至应用程序)。


回复您的评论

如果我在应用程序第一次访问时启动它们,我应该在哪里保存它们?全局变量?

这里自然要做的事情是把它作为它自己的模块,这将给你一个很好的地方,让你有其他的方法来操作列表&持久化到存储。如果你选择单例方法,那么你可以在第一次访问时加载资源,例如

ActivityType.js

var fs = require('fs');
var cache = null;
function loadCache(callback) {
    if (!cache) {
        fs.readFile('/path-to-strings', function (err, data) {
            if (!err) {
                // for the purpose of the example, lets assume you are storing the 
                // strings as a JSON object e.g. { 'key1': 'value1', 'key2': 'value2' }
                cache = JSON.parse(data);
                callback(null, cache);
            } else {
                callback(err, null);
            }
        });
    } else {
        callback(null, cache);
    }
};
module.exports = {
    get: function(key, callback) {
        loadCache(function(err, cache) {
            callback(err, (cache || {})[key]);
        });
    },
    add: function(key, value, callback) {
        loadCache(function(err, cache) {
            if (err) {
                if (callback) callback(err);
            } else {
                cache[key] = value;
            }
        });
    },
    remove: function(key, callback) {
        loadCache(function(err, cache) {
            if (err) {
                if (callback) callback(err);
            } else {
                delete cache[key];
            }
        });
    },
    save: function(callback) {
        loadCache(function(err, cache) {
            if (err) {
                if (callback) callback(err);
            } else {
                var data = JSON.stringify(cache, null, 4); // save formatted for easier editing
                fs.writeFile('/path-to-strings', data, callback);   
            }
        });
    }
};

App.js

var ActivityType = require('./ActivityType');
...
ActivityType.get('UNAC', function(err, text) {
    if (!err) {
        console.log(text);
    } else {
        console.log('Unable to load string');
    }
});
ActivityType.add('UCAP', 'User changed account password');
ActivityType.remove('UNAC');
ActivityType.save(function(err) {
    if (!err) {
        console.log('Saved successfully!');
    } else {
        console.log('Unable to save strings');
    }
});

或者,你可以有一个显式的loadinit方法,你可以在应用程序启动时调用。

重新部署应用程序的成本有多高?

这不是我可以回答的问题,因为这里没有足够的信息,只有你知道重新部署你的应用程序会有多昂贵。无论如何,更新DB记录或更改资源文件肯定比重新部署要简单得多。

最新更新