Over-fethcing && Under-fetching


緒論


RESTful APIでデータを受信すると、
次の場合があります.
  • モデルデータの一部のみ
  • マルチモデルデータの一部が必要です.
  • しかし、これらの状況では、不要な大量のデータを受信する必要があります.
    これは主にRESTful APIがjsonタイプに情報を伝達するためである.
    1番の取り方と2番のUnder-fetchingについて詳しく説明します

    定義済み


    使用しているのはmongoDBmongooseのSchema機能で次のデータモデルを処理しています.expressプロジェクト設定を完了する前提でコントローラからデータ要求を出す.ViewTemplateは[PUG]を使用します.
  • userSchema && userModel(User)
  • const userSchema=mongoose.Schema({
      email: {type:String, required:true},
      username: {type:String, required:true},
      password: {type:String, required:true},
      description: {type:String},
      imageArray: [ {type:mongoose.Schema.Types.ObjectId, ref:"Image"} ],
    });
    const userModel=mongoose.model("User",userSchema);
  • imageScheam && imageModel(Image)
  • const imageSchema=mongoose.Schema({
      title: {type:String, required:true, default:"untitled"},
      imageURL: {type:String, required:true, default:null},
      owner: {type:mongoose.Schema.Types.ObejctId, ref:"User"},
    });
    const imageModel=mongoose.model("Image",imageSchema);

    Over-fetching


    1行の説明


    1つのターゲットがわずかなデータしか必要としない場合でも、そのターゲットのすべてのデータが受信されます.

    コードの例


    ユーザー検索に関連するコントローラを作成する必要があります.
    「H」を入力すると、プレイヤーの名前に「H」がある人を探します.
    import userModel from "../model/userModel";
    export const searchUserGet=async(req,res)=>{
      const { saerch:username }=req.body;
      
      const userDB=await userModel.findOne({username});
      return (userDB) ?
        res.render(".../view/screen/searchPage.pug",{ userDB }) : 
        res.render(".../view/screen/searchPage.pug",{ userDB:null, error:"404 Not Found"});
    };
    上のコードで、以下のプレイヤーが並んでいます.
    const userDB=[
      {
        id:124151351421
        email:"[email protected]",
        username:"Anonymous001",
        password:"malktmkqelmtlkeqm",
        description:"I'm anonymous! Nice to meet you",
        imageArray:[]
      },
      {
        id:521513214122 
        email:"[email protected]",
        username:"Hello",
        password:"qtklmeqkltmkqler"
        description:"Hello It's a Test Object Array",
        imageArray:[ObjectId(142142151),ObjectId(15125124)]
      }
    ];
    ただし、View Templateでは次の情報のみが使用されます.
  • id:ユーザ固有値
  • ユーザー名:プレイヤー名
  • imageArray:アップロードした画像を残すか
  • そこで、次の問題が発生しました.
  • email、password:frontendは同様の機密情報を扱う
  • description:比較的大量のデータ空間を占有する情報を一緒に交換するホットスポット
  • これは、RESTful APIからデータを受信する際に発生する可能性のある現象で、「オーバーフェッチ」と呼ばれます.

    Under-fetching


    1行の説明


    N個のターゲットのデータを受信するには、N回のAPI呼び出しが必要である

    コードの例


    Instagramをクローンコードします.
    多くの機能の中で、個人のフィードバックの中で3つの基本的な機能の画面を展示したいと思っています.
  • 個人種子
  • 詳細画像
  • 注目・確認注目
  • 2番と3番のために、MongooseSchemaごとに新しいアイテムを追加し、DBを転送しました.
  • userSchema
  • userSchema=mongoose.Schema({
      following:[{type:mongoose.Schema.Types.ObjectId, ref:"User"}],
      followed:[{type:mongoose.Schema.Types.ObjectId, ref:"User"}]
    )};
  • imageScheam
  • imageSchema=mongoose.Schema({
      descirption:{type:String},
      hahstags:{type:String},
    });
    コントローラを作成する前に、
    各画面に必要なモデルの情報を考えてみましょう.

  • 個人購読ソース
    1.1. userModel

  • 詳細画像
    2.1. userModel
    2.2. imageModel

  • 注目する
    3.1. userModel
  • 各セクションのコントロールを作成します
    import userModel from "../model/userModel";
    import imageModel from "../model/imageModel";
    
    export const feedGet=async(req,res)=>{
      const { id:userId }=req.params;
      
      const userDB=await userModel.findById({id}).populate("Image");
      return (userDB) ?
        res.render(".../view/template/userFeed",{ userDB } :
        res.render(".../view/template/userFeed",{ userDB:null, error:"404" };
    };
    
    export const detailGet=async(req,res)=>{
      const { id:imageId }=req.params;
      
      const imageDB=await imageModel.findById({id}).populate("User");
      return (imageDB) ?
        res.render(".../view/template/imageDetail",{ imageDB } :
        res.render(".../view/template/imageDetail",{ imageDB:null, error:"404" };
    };
    export const followListGet=async(req,res)=>{
      const { id:userId }=req.params;
      
      const userModel=await userModel.findById({id});
      return (userModel) ?
        res.render(".../view/template/followList",{ imageDB } :
        res.render(".../view/template/followList",{ imageDB };
    };
    上のコードを見ればわかりますが、
    userModelとimageModelのデータを呼び出す場合は、2行のコードを記述する必要はありません.
    populate method(Mongoose)を使用して1行のコードで呼び出されるのがわかります.
    でも、
    morganのようなステータス管理モジュールをインストールし、API呼び出し履歴を表示します...
    複数のAPI呼び出し履歴が表示されます.
    GET/userModel/:id
    GET/imageModel/:id
    このように
    1つのコントローラ(サービス、ページなど)
    複数のAPI呼び出しが発生した場合をUnder-fetchingと呼ぶ.

    ソリューション


    では、これらの問題をどのように解決しますか?
    代表的な解決策はGraphQL