NodeJS-(4):階層化


プロジェクト構造設計


今回のリリースでは、プロジェクト構造設計において最も重要な階層、特にExpressについてまとめます.

1-2. 構成部品を階層化し、Expressを境界に配置します。


各コンポーネントは、Web、論理、およびデータ・アクセス・コード(DAL)の階層化を行う必要があります.これは、開発者のパーティクルにキャラクタをきれいに割り当て、シミュレーションオブジェクト(mock)を作成するために、予想されるバグをキャプチャできるため、セルテスト中に非常に役立ちます.

router.get('/:banner_id', jwt.graphql.isLoggedIn, async (req, res) => {
   try {
       ///////////// 1. client에서 넘어오는 데이터 처리
       const { banner_id } = req.params; 
       
       ///////////// 2. DB에서 원하는 데이터 조회
       var transaction = await sequelize.transaction();
       const banners = await Banner.findOne({
           where: {
               id: banner_id
           },
           include: [
               {
                   model: Banner_sub_img,
                   order: [
                       ['order', 'ASC']
                   ]
               }
           ],
           transaction
       });
       await transaction.commit();

       ///////////// 3. client에 response 전송
       res.status(200).json(response.success(resMessage.READ_SUCCESS, banners));
   } catch (err) {
       error_handling.normal(err, res, transaction);
   }
});
前述したようにGet法の処理をExpressのrouterとコールバック関数の形式と混合するのは最悪である.一般的なモードであるにもかかわらず、APIサーバ開発者は通常、Express req、resをビジネスロジックと混同します.
その欠点は、アプリケーション内部の機能を相互に依存させ、Expressでしかアクセスできないことです.テストはpostman以外では不可能(直接書くのは難しい)という欠点もあり、修正するのも面倒な欠点があります.Cron作業ではそうでした.

3 Layer Architecture


3階層アーキテクチャは、ビジネスロジックを分離し、コントローラ、サービス層、データ・アクセス層の3つの階層に分けることを目的としています.

  • コントローラ:クライアントとの通信に必要なreq、resの処理

  • サービス:ビジネスロジックの処理

  • Data Access Laer : JPA, ORM, MYBATIS.. データベースつうしんしょり
    上記3段階に分けた最大の利点は拡張性である.レイヤ別に分離する利点は、必要に応じていつでも独立してサイズを調整または変更できることです.

  • Controller

  • クライアントは、サービス
  • に要求して転送する.
  • サービスは、完了したデータをクライアント
  • に返す.
    X
  • データなどのビジネスロジックを絶対追加
    route.post('/', 
      validators.userSignup, // this middleware take care of validation
      async (req, res, next) => {
        // ... The actual responsability of the route layer.
        const userDTO = req.body;
    
        // ... Call to service layer.
        const { user, company } = await UserService.Signup(userDTO);
    
        // ... Return a response to client.
        return res.json({ user, company });
    });
    reqは、前回のパブリケーションで説明したExpressと論理を分離するために使用されることに注意してください.bodyはuserDTOに変更されました.

    Service


    サービス・レイヤは、残りのアプリケーションですべてのビジネス・ロジックをカプセル化および抽象化します.
    やるべきこと

  • ビジネスロジックを含める

  • データ・アクセス・レイヤを使用してデータベースと対話する

  • コントローラレイヤに送信するデータを返します
    やるべきでないこと

  • 直接使用

  • クライアントres

  • データベース・アクセス
  • module.exports = {
        readAll: () => {
            return new Promise(async (resolve, reject) => {
                // ... User DAL methods
                const city = await City.findAll({});
                if(city.length == 0) {
                    resolve({
                        json: utils.successFalse(sc.NO_CONTENT, rm.CITY_EMPTY)
                    });
                    return;
                }
                if (!city) {
                    resolve({
                        json: utils.successFalse(sc.INTERNAL_SERVER_ERROR, rm.CITY_READ_ALL_FAIL)
                    });
                    return;
                }
                resolve({
                    json: utils.successTrue(sc.SUCCESS, rm.CITY_READ_ALL_SUCCESS, city)
                });
            });
        }
    }

    Data Access Layer

  • データベースとのインタラクション
  • 通常は
  • SequelizeというORMが使用されます
  • または直接収集クエリー、
  • をサービス層を介して呼び出す