15

ルートを動的に作成する Express.js を使用してシンプルな CMS を作成しようとしています。次のようなデータベースから JSON を取得します。

pagesfromdb = {
    home = {
        paths = ['/','/home','/koti'],
        render = 'home.ejs',
        fi_FI = {html='<h1>Hei maailma!</h1>'},
        en_US = {html='<h1>Hello World!</h1>'}
    },
    about = {
        paths = ['/about','/tietoja'],
        render = 'general.ejs',
        fi_FI = {html='Tietoja'},
        en_US = {html='About Us'}
    }
}

次のようにルートを作成するオブジェクトを反復処理します。

Object.keys(pagesfromdb).forEach(function(key) {
    var page = pagesfromdb[key];
    app.get(page.global.paths,function(req, res){
         res.render(page.render, page[language]);
    });
});

現在、すべてが正常に機能しています。しかし問題は、ユーザーがコンテンツとパスを変更するたびに、ノード アプリ全体を再起動する必要があることです。ルートを削除するための API 呼び出しが見つかりませんでした。

app.get で設定された古いルートを安全に削除する方法はありますか? 私もそれをする必要がありますか?

この種のルーティングを行うためのより良い方法はありますか? 組み込み関数を使用でき、高速で、正規表現をサポートしているため、この方法が気に入っています。

app.routes = nul で app.routes 全体を削除しようとしましたが、何もしませんでした。古いルートがまだ残っていました。

それらを実際に削除したことの1つは、

delete app._router.map.get;
app._router.map.get = [];

しかし、これは実際にそれらを削除し、安全に使用できるので、ルーターが再配置され続けた場合に大量の RAM をハイジャックすることはありませんか?

4

3 に答える 3

16

@supermova がコメントで述べたように、Express はオンザフライで更新できます。考慮すべきもう 1 つのアーキテクチャは、従来の CMS に似たものです (たとえば、Wordpress など)。他の CMS では、すべてのリクエストが同じ「コールバック」に送られ、すべてのリクエストその URL に提供するページをデータベースで検索します。

app.get('/*', function (req, res) {
   db.findPage({ slug: req.url}, function (err, pageData) {
       res.render('page-template', {
           pageContent: pageData.content,
           pageTitle: pageData.title
       });
   });
});

この方法の結果として速度が大幅に低下しますが、最終的にはより正気だと思います。速度が大きな問題である場合は、キャッシング システム (Varnish など) をセットアップできますが、オンザフライで Express ルートを変更するアプローチには頭痛の種があります。たとえば、2 つの Web サーバーに拡張する必要がある場合はどうすればよいでしょうか? サーバーAが「ページの作成」リクエストを受け取り、ルートを更新することを知っている場合、それらをどのように同期させますか?サーバーBはどうですか? データベースに送信されるすべてのリクエストで、水平方向のスケーリングを改善できます。

于 2013-03-12T20:07:36.587 に答える
1

実行時にルートを作成または破棄しようとすると、非常に注意が必要です。自分でデータ構造を変更することはできますが、これらが API として文書化されているとは思わないため、Express をアップグレードすると、この問題が発生する危険があります。

これは、データベース オブジェクトごとに新しいルートを作成する場合、メモリの制約としても機能する可能性があります。

このように見てください...新しいルートは必要ありません。URL を既存のルートに追加したい。ルートを追加する場合は、URL を特定の機能にマップする必要があることを意味します。ただし、各 URL を同じ関数にマッピングしています。本質的に、副作用によってルートを追加しているだけです。あなたが気にしているのは、動的な URL のセットが特定の関数にマップされていることです。

代わりにワイルドカードを使用して、URL パターンを特定の関数にマップできますか?

app.get('/pages/*', function(req, res) {
    var page = pagesfromdb[key];
    if (page != null) {
        res.render(page.render, page.language)
    }
    else {
        res.send(404);
    }
});

また、express レイヤーの外側で pagesfromdb マッピングを管理します。データベースへの直接アクセス、キャッシュ + データベース アクセス、またはタイマーベースのリフレッシャーなど、最適なパフォーマンスを発揮するものを使用できます。

于 2013-03-12T20:22:02.810 に答える