2016-04-15 6 views
7

私は最近、React-Redux-Express-Mongooseスタックを使用していくつかの等身大/ユニバーサルプロジェクトを構築しました。同形(React/Redux/Express/Mongo)アプリケーションのデータモデルとビジネスロジック

私のマングースモデルには、多くのビジネスロジックが含まれています。非常に基本的な例(言い訳私のES6)のよう:

import mongoose, {Schema} from 'mongoose'; 

const UserSchema = new Schema({ 
    name: String, 
    password: String, 
    role: String 
}); 

UserSchema.methods.canDoSomeBusinessLogic = function(){ 
    return this.name === 'Jeff'; 
}; 

UserSchema.methods.isAdmin = function(){ 
    return this.role === 'admin'; 
}; 

これは、これらのモデルは、プレーンなJSONオブジェクトとしてブラウザで水和されているがとき、サーバー上のすべての素晴らしいですが、私は、この同じビジネスを再実装する必要がありますある種のReactコンポーネントやRedux Reduceのロジックがあります。私はこれに最も近づける方法が不思議です。

Mongooseを読んでいることから、ブラウザのサポートは限られているようです。私の主なオプションは次のとおりです:

  • すべてのビジネスロジックをいくつかの「通常の」JSクラスに移動し、それらをすべてその場でインスタンス化します。たとえば:

    # JS Class definition - classes/user.js 
    export default class User { 
        constructor(data = {}){ 
         Object.assign(this,data); 
        } 
    
        canDoSomeBusinessLogic(){ 
         return this.name === 'Jeff'; 
        }; 
    
        isAdmin(){ 
         return this.role === 'admin'; 
        } 
    } 
    
    # Server - api/controllers/user.js 
    import UserClass from 
    User.findById(1,function(err,user){ 
        let user = new UserClass(user.toJSON(); 
    }); 
    
    # Client - reducers/User.js 
    export default function authReducer(state = null, action) { 
        switch (action.type) { 
        case GET_USER: 
         return new UserClass(action.response.data); 
        } 
    } 
    
    # Client - containers/Page.jsx 
    import {connect} from 'react-redux'; 
    
    @connect(state => ({user: state.user})) 
    export default class Page extends React.Component { 
        render(){ 
         if(this.props.user.isAdmin()){ 
         // Some admin 
         } 
        } 
    } 
    
  • は、いくつかの静的なヘルパー関数にすべてのビジネスロジックを移動します。私は基本的に再び全体の一例を書き出すはなくなります。

    # helpers/user.js 
    export function isAdmin(user){ 
        return user.role === 'admin'; 
    } 
    

を私は上記の2の違いは、単に個人的な好みであると仮定します。しかし、同型アプリやデータモデリングについて他の誰かが考えている人はいますか?あるいは、この問題を解決する人々のオープンソースの例を見たことがあります。

上記の拡張として、isomorphic save()関数はどうでしょうか? User.save()。したがって、クライアント上で呼び出された場合、関連するAPIエンドポイントにPOSTを実行し、サーバー上で実行すると、Mongoose save()関数を呼び出します。

答えて

1

スポイラー:反論を期待する。それを行う正しい方法はありません。すべての

まずあなたは私たちが話している内容を正確に把握するように、私は、difference between isomorphic and universalを明確にしたい:

同型がシームレスにクライアント側およびサーバー側のレンダリングの切り替えの機能的な側面であります状態を失うことなく。ユニバーサルは、特定のJavaScriptコードを複数の環境で実行できることを強調するために使用される用語です。

普遍的なアプリケーションに多くの抽象化が必要ですか?

普遍的なアプリケーションを使用するには、クライアントと同じコードを読み込む両方のアプリをプリレンダリングするサーバーを用意するのが一般的です。アプリケーションをプリレンダリングするのと同じサーバーからAPIを実行することはできますが、私はむしろそれをプロキシして別のプロセスで実行します。

Erikrasよく知られた定型文がグローバルに依存関係を共有するために彼のユニバーサルアプリを使用していますリアクト+ API、およびコード:

私はあなたに二つの異なる反応させ、リポジトリをお見せしましょうページをプリレンダリングするサーバーとクライアントの間で可能ではあるが、彼はバリデーションを共有していない。 Survey API validationSurvey client validation

WellyshenにはAPIはありませんが、サーバーとクライアントの間でのみ、彼の依存関係とコードも共有しています。 serverはルート、店舗やクライアントアプリケーションによって実行されているすべてのものをロードします。それは同形を提供することです。

は、それが一つの場所ですべての検証を移動するかどうかはあなた次第である、と述べました。私はおそらく、あなたが実際にそれを助けることができる電子メールの検証のような、複雑な検証の場合にはそれを検討するだろう。 (それは、電子メールの検証のためにすでにvalidatorを持って、単なる一例でした)。特定の場面では、ベストプラクティスであることではないとはいえ、APIの検証に依存する方が便利かもしれません。

例のような単純な検証は、とにかくredux-formで簡単に実行できます。これは、APIで直接変換する方法がないことがわかります。代わりに、あなたはおそらくそれにexpress-validatorを探している必要があります。

もう1つのことは、非常に人気のあるReactの定型文がAPIとクライアントを一緒に持っているにもかかわらず、React +サーバー側のレンダリングとAPIの2つのリポジトリで作業する傾向があります。長期的には、それは完全に独立したコードとなります。 organizing-large-react-applications

関連する問題