সত্তা ফ্রেমওয়ার্ক সত্তা - ওয়েব পরিষেবা থেকে কিছু ডেটা - সেরা আর্কিটেকচার?


10

আমরা বর্তমানে কয়েকটি ওয়েব অ্যাপ্লিকেশন জুড়ে অ্যান্টি ফ্রেমওয়ার্কটি একটি ওআরএম হিসাবে ব্যবহার করছি এবং এখন অবধি এটি আমাদের উপযোগী হিসাবে আমাদের সমস্ত ডেটা একক ডাটাবেসে সংরক্ষণ করা হয়। আমরা সংগ্রহস্থল প্যাটার্নটি ব্যবহার করছি, এবং পরিষেবাগুলি (ডোমেন স্তর) রয়েছে যা এগুলি ব্যবহার করে এবং EF সত্তাগুলি সরাসরি এএসপি.নেট এমভিসি নিয়ন্ত্রকদের কাছে ফিরিয়ে দেয়।

তবে, একটি তৃতীয় পক্ষের এপিআই (ওয়েব সার্ভিসের মাধ্যমে) ব্যবহার করার জন্য একটি প্রয়োজনীয়তা এসেছে যা আমাদের ডেটাবেজে ব্যবহারকারীর সাথে সম্পর্কিত অতিরিক্ত তথ্য দেবে। আমাদের স্থানীয় ব্যবহারকারীর ডাটাবেসে, আমরা একটি বাহ্যিক আইডি সঞ্চয় করব যা আমরা অতিরিক্ত তথ্য পেতে API কে সরবরাহ করতে পারি। এখানে বেশ কিছু বিস্তৃত তথ্য পাওয়া যায়, তবে সরলতার জন্য, এর মধ্যে একটি ব্যবহারকারীর সংস্থার (নাম, পরিচালক, ঘর, কাজের শিরোনাম, অবস্থান ইত্যাদি) সম্পর্কিত। এই তথ্যটি আমাদের ওয়েব অ্যাপ্লিকেশনগুলিতে বিভিন্ন জায়গায় ব্যবহার করা হবে - একক জায়গায় ব্যবহারের বিপরীতে।

সুতরাং আমার প্রশ্ন হ'ল, এই তথ্যকে জনবহুল ও অ্যাক্সেস করার সর্বোত্তম জায়গাটি কোথায়? যেহেতু এটি বিভিন্ন স্থানে ব্যবহৃত হয়, ওয়েব অ্যাপ্লিকেশনটিতে আমরা যেখানেই এটি ব্যবহার করি না কেন এটি অ্যাড-হক ভিত্তিতে আনা সত্যিকার অর্থে বুদ্ধিমানের কাজ নয় - তাই ডোমেন স্তর থেকে এই অতিরিক্ত ডেটা ফেরানো বোধগম্য।

আমার প্রাথমিক চিন্তাটি কেবল একটি র‌্যাপার মডেল ক্লাস তৈরি করা ছিল যা EF সত্তা (EFUser) এবং একটি নতুন 'ApiUser' ক্লাসে নতুন তথ্য থাকবে - এবং যখন আমরা কোনও ব্যবহারকারী পাই, তখন আমরা EFUser পাই এবং তার পরে অতিরিক্ত পেতে পারি এপিআই থেকে তথ্য এবং ApiUser অবজেক্টটি পপুলেট করুন। তবে, একক ব্যবহারকারী পাওয়ার ক্ষেত্রে এটি ঠিক থাকবে, একাধিক ব্যবহারকারী পাওয়ার সময় এটি পড়ে যায়। ব্যবহারকারীর তালিকা পাওয়ার সময় আমরা API টি হিট করতে পারি না।

আমার দ্বিতীয় চিন্তাটি ছিল কেবলমাত্র EFUser সত্তায় একটি সিঙ্গলটন পদ্ধতি যুক্ত করা যা এপিউসারকে ফেরত দেয় এবং যখন প্রয়োজন হয় তখন এটি তৈরি করে। এটি কেবল যখন আমাদের প্রয়োজন হয় তখন এটি অ্যাক্সেস করার কারণে উপরের সমস্যাটি সমাধান করে।

বা চূড়ান্ত চিন্তাটি ছিল আমাদের ডাটাবেসে ডেটার একটি স্থানীয় অনুলিপি রাখা এবং যখন ব্যবহারকারী লগ ইন করে এটি এপিআইয়ের সাথে সিঙ্ক্রোনাইজ করে। এটি কেবলমাত্র একটি সিঙ্ক্রোনাইজেশন প্রক্রিয়া হিসাবে এটি ন্যূনতম কাজ - এবং আমাদের কাছে আঘাতের ওভারহেড নেই DB এবং API প্রতিবার আমরা ব্যবহারকারীর তথ্য পেতে চাই। যাইহোক, এর অর্থ দুটি স্থানে ডেটা সংরক্ষণ করা এবং এর অর্থ হ'ল যে কোনও ব্যবহারকারীর জন্য কিছুক্ষণ লগইন করা হয়নি তার ডেটা পুরানো।

এই ধরণের পরিস্থিতিটি কীভাবে পরিচালনা করা যায় সে সম্পর্কে কারও কি কোনও পরামর্শ বা পরামর্শ আছে?


it's not really sensible to fetch it on an ad-hoc basis- কেন? পারফরম্যান্সের কারণে?
রবার্ট হার্ভে

আমি কোনও অ্যাড-হক ভিত্তিতে এপিআই-তে আঘাত করা বলতে চাই না - আমি কেবলমাত্র বিদ্যমান সত্তা কাঠামোটিকে যেমন আছে ঠিক তেমনই বোঝাতে চাইছি এবং তারপরে প্রয়োজনে যখন ওয়েব অ্যাপ্লিকেশনটিতে এপিআই অ্যাড-হককে কল করব - আমি কেবল বোঝাতে চাইছি এটি হবে না বোধগম্য হওয়ায় এটি প্রচুর জায়গায় করা দরকার।
স্টিভহেটার

উত্তর:


3

আপনার ক্ষেত্রে

আপনার ক্ষেত্রে তিনটি বিকল্পই কার্যকর। আমি মনে করি যে সর্বোত্তম বিকল্পটি সম্ভবত আপনার ডেটা উত্স সিঙ্ক করার জন্য কোথাও অ্যাসপিএন অ্যাপ্লিকেশনটি অবগত নয়। এটি হ'ল প্রতিবার অগ্রভাগে দুটি ফেচ এড়িয়ে চলুন, নীরবে ডিবির সাথে এপিআই সিঙ্ক করুন)। সুতরাং যদি এটি আপনার ক্ষেত্রে একটি কার্যকর বিকল্প - আমি বলি এটি করুন।

অন্যান্য উত্তরের মতো আপনি যখন একবার 'একবার' এনে ফেলেন এমন একটি সমাধান খুব কার্যকর হবে বলে মনে হচ্ছে না কারণ এটি কোথাও প্রতিক্রিয়া অব্যাহত রাখে না এবং এএসপি.নেট এমভিসি কেবলমাত্র প্রতিটি অনুরোধের জন্য বার বার আনবে।

আমি সিঙ্গেলটন এড়িয়ে চলতাম, সাধারণ কারণে প্রচুর কারণে এটি মোটেই ভাল ধারণা বলে আমি মনে করি না।

যদি তৃতীয় বিকল্পটি ব্যবহারযোগ্য না হয় - একটি বিকল্প হ'ল এটি অলসভাবে লোড করা। এটি হ'ল, কোনও শ্রেণি সত্তাকে প্রসারিত করুন এবং এটি ভিত্তিতে প্রয়োজনের ভিত্তিতে এটিআইপিতে আঘাত করেছে । এটি একটি অত্যন্ত বিপজ্জনক বিমূর্ততা যদিও এটি আরও বেশি যাদু এবং অ-স্পষ্ট রাষ্ট্র।

আমার ধারণা এটি বেশ কয়েকটি প্রশ্নের কাছে সত্যিই ফুটে উঠেছে:

  • এপিআই কল ডেটা কতবার পরিবর্তন হয়? না প্রায়ই? তৃতীয় বিকল্প। ঘন ঘন? হঠাৎ তৃতীয় বিকল্পটি খুব কার্যকর নয়। আমি নিশ্চিত নই যে আমি আপনার মতো অ্যাড-হক কলগুলির বিপক্ষে।
  • একটি এপিআই কল কত ব্যয়বহুল? আপনি কি প্রতি কল প্রদান করেন? তারা কি দ্রুত? ফ্রি? যদি তারা দ্রুত হয়, প্রতিবার একটি কল করা কার্যকর হতে পারে, যদি তারা ধীর হয় তবে আপনার কোনও জায়গায় ভবিষ্যদ্বাণী করা উচিত এবং কলগুলি করা দরকার। যদি তাদের অর্থ ব্যয় হয় - এটি ক্যাশে দেওয়ার জন্য একটি বড় উত্সাহ।
  • প্রতিক্রিয়া সময়টি কত দ্রুত হতে হবে? স্পষ্টতই দ্রুততর ভাল, তবে সরলতার জন্য গতি ত্যাগ করা কিছু ক্ষেত্রে এটির পক্ষে উপযুক্ত হতে পারে, বিশেষত যদি এটি সরাসরি ব্যবহারকারীর মুখোমুখি না হয়।
  • আপনার ডেটা থেকে এপিআই ডেটা কতটা আলাদা? এগুলি কি দুটি ধারণামূলকভাবে আলাদা জিনিস? যদি তা হয় তবে এটিআইপি ফলাফলটি সরাসরি ফলাফলের সাথে ফেরত দেওয়ার চেয়ে কেবল বাহিরের বাইরে প্রকাশ করা আরও ভাল and

উদ্বেগের বিচ্ছেদ সম্পর্কে একটি বা দুটি শব্দ

এখানে উদ্বেগের বিচ্ছেদ সম্পর্কে ববসন যা বলছেন তার বিরুদ্ধে তর্ক করার অনুমতি দিন। দিনের শেষে - সেই মত সত্তাগুলিতে সেই যুক্তি স্থাপন করা উদ্বেগকে পৃথক করা ঠিক খারাপ হিসাবে লঙ্ঘন করে।

এ জাতীয় সংগ্রহস্থল থাকা দুশ্চিন্তার কারণটিকে বিরক্ত করে just ব্যবসায় যুক্তিযুক্ত স্তরে উপস্থাপনা কেন্দ্রিক যুক্তি যুক্ত করে । আপনার সংগ্রহস্থলটি হঠাৎ করে উপস্থাপনা সম্পর্কিত জিনিসগুলি সম্পর্কে আপনি সচেতন হন যেমন আপনি কীভাবে আপনার এসপ নেটওয়ান এমভিসি নিয়ন্ত্রণকারীগুলিতে ব্যবহারকারীকে প্রদর্শন করেন।

ইন এই সংশ্লিষ্ট প্রশ্ন আমি একটি নিয়ামক থেকে সরাসরি সত্ত্বা অ্যাক্সেস সম্পর্কে জিজ্ঞাসা করেছি। আমাকে সেখানে উত্তরগুলির একটি উদ্ধৃত করার অনুমতি দিন:

"কাস্টম পিজ্জার দোকান বিগপিজায় আপনাকে স্বাগতম, আমি কি আপনার আদেশ নিতে পারি?" "আচ্ছা, আমি জলপাইয়ের সাথে পিজ্জা পেতে চাই তবে উপরে টমেটো সস এবং নীচে পনির এবং এটি চুলাতে 90 মিনিট বেক করুন যতক্ষণ না এটি কালো এবং গ্রানাইটের সমতল পাথরের মতো শক্ত।" "ঠিক আছে স্যার, কাস্টম পিজ্জা আমাদের পেশা, আমরা এটি তৈরি করব।"

ক্যাশিয়ার রান্নাঘরে যায়। "কাউন্টারে একটি সাইকো রয়েছে, সে সাথে একটি পিজ্জা রাখতে চায় ... এটি গ্রানাইটের একটি শিলা সহ ... অপেক্ষা করুন ... আমাদের প্রথমে একটি নাম থাকা দরকার", সে কুককে বলে।

"না!", কুক চিৎকার করে বলে, "আবার নয়! আপনি জানেন আমরা ইতিমধ্যে এটি চেষ্টা করেছি।" তিনি ৪০০ পৃষ্ঠাগুলি সহ একটি কাগজের স্ট্যাক নিলেন, "এখানে আমাদের ২০০৫ সাল থেকে গ্রানাইটের রক রয়েছে, কিন্তু ... এর পরিবর্তে জলপাই ছিল না, তবে পাপ্রিকা ছিল ... বা এখানে শীর্ষ টমেটো ছিল ... তবে গ্রাহক এটি চেয়েছিলেন মাত্র আধ মিনিট বেকড। " "হয়তো আমাদের এটাকে টপটোমাটোগ্রানাইটরক স্পেশিয়াল বলা উচিত?" "তবে এটি নীচে পনিরটিকে বিবেচনায় নেয় না ..." ক্যাশিয়ার: "এটিই বিশেষভাবে প্রকাশ করার কথা রয়েছে।" "তবে পিরামিডের মতো পিজ্জা রক তৈরি হওয়াও বিশেষ বিশেষ হবে", কুক জবাব দেয়। "হুমমম ... এটা কঠিন ...", হতাশ ক্যাশিয়ার বলে।

"আমার পিজা ওভেনের আগেই আছে?", হঠাৎ এটি রান্নাঘরের দরজা দিয়ে চেঁচিয়ে উঠল। "আসুন এই আলোচনাটি বন্ধ করুন, কেবল আমাকে কীভাবে এই পিজ্জা তৈরি করবেন তা বলুন, আমরা দ্বিতীয়বার এই জাতীয় পিজ্জা পাব না", কুক সিদ্ধান্ত নিয়েছে। "ঠিক আছে, এটি জলপাইয়ের সাথে পিজ্জা, তবে উপরে টমেটো সস এবং নীচে চিজ এবং 90 মিনিটের জন্য চুলায় সিদ্ধ করুন যতক্ষণ না এটি কালো এবং গ্রানাইটের সমতল পাথরের মতো শক্ত।"

(বাকি উত্তরটি পড়ুন, এটি সত্যিই দুর্দান্ত ইমো)।

এটি একটি ডাটাবেস আছে তা উপেক্ষা করা নির্বোধ - একটি ডাটাবেস আছে, এবং আপনি যে কতটা কঠোর বিমূর্ত করতে চান তা তা কোথাও যাচ্ছে না। আপনার অ্যাপ্লিকেশনটি ডেটা উত্স সম্পর্কে সচেতন হবে । আপনি 'এটি হট অদলবদল' করতে সক্ষম হবেন না। ওআরএমগুলি দরকারী তবে তারা যে সমস্যাটি সমাধান করেছেন তা কতটা জটিল এবং প্রচুর পারফরম্যান্স কারণে (উদাহরণস্বরূপ এন + 1 নির্বাচন করুন) এর কারণে তারা ফাঁস হন।


আপনার খুব পূর্ণ প্রতিক্রিয়ার জন্য ধন্যবাদ @ বেঞ্জামিন। আমি প্রথমে উপরে ববসনের সমাধান ব্যবহার করে একটি প্রোটোটাইপ তৈরি শুরু করেছি (তিনি তার উত্তর পোস্ট করার আগেও), তবে আপনি কয়েকটি গুরুত্বপূর্ণ বিষয় উত্থাপন করেন। আপনার প্রশ্নের জবাব দিতে,: - এপিআই কলটি খুব ব্যয়বহুল নয় (তারা নিখরচায় এবং দ্রুত)। - ডেটার কিছু অংশ মোটামুটি নিয়মিত পরিবর্তিত হবে (কিছু কয়েক ঘন্টা কয়েক ঘন্টা এমনকি)। - গতি মোটামুটি গুরুত্বপূর্ণ, তবে অ্যাপ্লিকেশনটির শ্রোতাগুলি এমন যে দ্রুত লোডিং দ্রুততর করা একটি চূড়ান্ত প্রয়োজনীয়তা নয়।
স্টিভহেটার

@ স্টেভেহাইটার সেক্ষেত্রে আমি ক্লায়েন্ট পক্ষ থেকে সম্ভবত এপিআই-তে কলগুলি সম্পাদন করব। এটি সস্তা এবং দ্রুত এবং এটি আপনাকে সূক্ষ্ম দানাদার নিয়ন্ত্রণ দেয়।
বেনজামিন গ্রুয়েনবুম

1
এই উত্তরগুলির ভিত্তিতে, আমি ডেটার স্থানীয় অনুলিপি রাখার দিকে কম ঝুঁকছি। আমি প্রকৃতপক্ষে পৃথকভাবে API টি উন্মুক্ত করার দিকে ঝুঁকছি এবং সেই সাথে অতিরিক্ত ডেটা পরিচালনা করছি। আমি মনে করি এটি @ ববসনের সমাধানের সরলতার মধ্যে একটি ভাল সমঝোতা হতে পারে, তবে কিছুটা বিচ্ছিন্নতাও যুক্ত করেছে যা সম্পর্কে আমি কিছুটা বেশি আরামদায়ক। আমি এই কৌশলটি আমার প্রোটোটাইপটিতে দেখব, এবং আমার অনুসন্ধানগুলি (এবং অনুগ্রহ পুরষ্কার!) দিয়ে রিপোর্ট করব।
স্টিভহেটার

@ বেনজামিন গ্রেনবাউম - আমি নিশ্চিত নই যে আমি আপনার যুক্তি অনুসরণ করেছি। কীভাবে আমার পরামর্শ উপস্থাপনা সম্পর্কে ভাণ্ডার সচেতন করে তোলে? অবশ্যই, এটি অবগত যে একটি এপিআই-ব্যাকড ফিল্ড অ্যাক্সেস করা হয়েছে তবে ভিউটি সেই তথ্যের সাথে কী করছে তার সাথে কিছুই করার নেই।
ববসন

1
আমি সমস্ত কিছুকে ক্লায়েন্ট-সাইডে সরিয়ে নেওয়ার পছন্দ করেছিলাম - তবে EFUser- তে একটি এক্সটেনশন পদ্ধতি হিসাবে (যা উপস্থাপনা স্তরটিতে একটি পৃথক সমাবেশে উপস্থিত রয়েছে)। পদ্ধতিটি কেবল API থেকে ডেটা ফেরত দেয় এবং একটি সিঙ্গলটন সেট করে যাতে এটি বারবার হিট না হয়। অবজেক্টের আয়ুকাল এত সংক্ষিপ্ত যে এখানে আমার একটি সিঙ্গলটন ব্যবহার করতে সমস্যা হয় না। এইভাবে কিছুটা বিচ্ছেদ রয়েছে, তবে আমি এখনও EFUser সত্তার সাথে কাজ করার সুবিধা পেয়েছি। সমস্ত উত্তরদাতাদের সহায়তার জন্য ধন্যবাদ। অবশ্যই একটি আকর্ষণীয় আলোচনা :)।
স্টিভহেটার

2

উদ্বেগের যথাযথ পৃথকীকরণের সাথে , সত্তা ফ্রেমওয়ার্ক / এপিআই স্তরের উপরে কোনও কিছুই ডেটা কোথা থেকে আসছে তা উপলব্ধি করা উচিত নয়। যদি এপিআই কল ব্যয়বহুল না হয় (সময় বা প্রক্রিয়াকরণের ক্ষেত্রে), এটি ব্যবহার করে এমন ডেটা অ্যাক্সেস করা ডাটাবেস থেকে ডেটা অ্যাক্সেস করার মতো স্বচ্ছ হওয়া উচিত।

এটি কার্যকর করার সর্বোত্তম উপায় EFUserহ'ল এটিতে অতিরিক্ত বৈশিষ্ট্য যুক্ত করা হবে যা প্রয়োজন হিসাবে API ডেটা অলসভাবে লোড করে। এটার মতো কিছু:

partial class EFUser
{
    private APIUser _apiUser;
    private APIUser ApiUser
    {
       get { 
          if (_apiUser == null) _apiUser = API.LoadUser(this.ExternalID);
          return _apiUser;
       }
    }
    public string CompanyName { get { return ApiUser.UserCompanyName; } }
    public string JobTitle{ get { return ApiUser.UserJobTitle; } }
}

বাহ্যিকভাবে, প্রথমবার হয় CompanyNameবা JobTitleব্যবহৃত হয় সেখানে একটি একক এপিআই কল আসবে (এবং এইভাবে একটি ছোট বিলম্ব হবে), তবে অবজেক্টটি ধ্বংস না হওয়া অবধি পরবর্তী সমস্ত কলগুলি ডাটাবেস অ্যাক্সেসের মতোই দ্রুত এবং সহজ হবে।


ধন্যবাদ @ বিবিসন ... এটি আসলেই আমি প্রাথমিক যাত্রা শুরু করলাম (কিছু এক্সটেনশন পদ্ধতি যুক্ত করে ব্যবহারকারীদের তালিকার জন্য বিশদ লোড যুক্ত করা হয়েছিল - উদাহরণস্বরূপ, ব্যবহারকারীদের তালিকার জন্য সংস্থার নাম প্রদর্শন করা)। এটি এখনও পর্যন্ত আমার প্রয়োজনের সাথে যথাযথভাবে উপযুক্ত বলে মনে হচ্ছে - তবে নীচে বেঞ্জামিন কিছু গুরুত্বপূর্ণ বিষয় উত্থাপন করেছে, তাই আমি এই সপ্তাহে মূল্যায়ন চালিয়ে যাচ্ছি।
স্টিভহেটার

0

একটি ধারণা হ'ল সর্বদা অতিরিক্ত তথ্য না রাখার জন্য অ্যাপিউসারকে সংশোধন করা। পরিবর্তে, আপনি এপিছু ব্যবহারের জন্য এপিউসারকে একটি পদ্ধতি রেখেছিলেন:

ApiUser apiUser = backend.load($id);
//Locally available data directly on the ApiUser like so:
String name = apiUser.getName();
//Expensive extra data available after extra call:
UserExtraData extraData = apiUser.fetchExtraData();
String managerName = extraData.getManagerName();

অতিরিক্ত ডেটার অলস লোডিং ব্যবহার করতে আপনি এটিকে সামান্যও সংশোধন করতে পারেন, যাতে আপনাকে এপিউসার অবজেক্ট থেকে ইউজারেক্সট্রাডেটা বের করতে হবে না:

//Extra data fetched on first get:
String managerName = apiUser.lazyGetExtraData().getManagerName();

এইভাবে, যখন আপনার একটি তালিকা থাকবে, তখন অতিরিক্ত ডেটা ডিফল্টভাবে আনা হবে না। তবে তালিকাটি ট্র্যাভার করার সময় আপনি এখনও এটি অ্যাক্সেস করতে পারবেন!


আপনি এখানে কী বোঝাতে চাইছেন তা নিশ্চিত নন - ব্যাকেন্ডেড.লোড () এ, আমরা ইতিমধ্যে একটি লোড করছি - সুতরাং এটিপিআইপি ডেটা লোড করবে কিনা?
স্টিভহেটার

আমি বলতে চাইছি স্পষ্টভাবে অনুরোধ না করা পর্যন্ত আপনার অতিরিক্ত লোডটি করা অপেক্ষা করা উচিত - অলস লোড এপিআই ডেটা।
আলেকজান্ডার টর্সলিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.