CRUD API: কোন ক্ষেত্রটি আপডেট করবেন তা আপনি কীভাবে নির্দিষ্ট করবেন?


9

আসুন ধরা যাক আপনার কাছে কিছু ধরণের ডেটা স্ট্রাকচার রয়েছে, যা একরকম ডাটাবেসেই টিকে থাকে। সরলতার জন্য, আসুন এই ডেটা স্ট্রাকচারকে কল করুন Person। আপনাকে এখন একটি সিআরইউডি এপিআই ডিজাইন করার দায়িত্ব দেওয়া হয়েছে, যা অন্যান্য অ্যাপ্লিকেশনগুলিকে এস তৈরি করতে, পড়তে, আপডেট করতে এবং মুছতে দেয় Person। সরলতার জন্য, ধরে নেওয়া যাক যে এই API টি কোনও একরকম ওয়েব পরিষেবার মাধ্যমে অ্যাক্সেস করা হয়েছে।

সিআরইউডির সি, আর এবং ডি অংশগুলির জন্য, নকশাটি সহজ। আমি সি # -র মতো কার্যকরী স্বরলিপি ব্যবহার করব - বাস্তবায়নটি SOAP, REST / JSON বা অন্য কিছু হতে পারে:

class Person {
    string Name;
    DateTime? DateOfBirth;
    ...
}

Identifier CreatePerson(Person);
Person GetPerson(Identifier);
void DeletePerson(Identifier);

আপডেট সম্পর্কে কি? প্রাকৃতিক জিনিসটি হবে

void UpdatePerson(Identifier, Person);

তবে আপনি কোন ক্ষেত্রটি Personআপডেট করবেন তা কীভাবে নির্দিষ্ট করবেন ?


যে সমাধানগুলি আমি নিয়ে আসতে পারি:

  • আপনার সর্বদা পাস করার জন্য একজন সম্পূর্ণ ব্যক্তি প্রয়োজন হতে পারে, অর্থাৎ ক্লায়েন্ট জন্ম তারিখ আপডেট করার জন্য এই জাতীয় কিছু করবে:

    p = GetPerson(id);
    p.DateOfBirth = ...;
    UpdatePerson(id, p);
    

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

    UpdatePerson(id, { "DateOfBirth": "2015-01-01" });
    

    - যা সঠিক দেখাচ্ছে - কেবলমাত্র তারিখ-জন্মের সময় পরিবর্তন করবে না, তবে অন্যান্য সমস্ত ক্ষেত্র শূন্য করতে পুনরায় সেট করবে।

  • আপনি যে সমস্ত ক্ষেত্র তা উপেক্ষা করতে পারেন null। যাইহোক, আপনি কীভাবে পরিবর্তন না করে DateOfBirth এবং ইচ্ছাকৃতভাবে এটিকে শূন্যে পরিবর্তন করার মধ্যে কোনও পার্থক্য করবেন ?

  • স্বাক্ষরটি এতে পরিবর্তন করুন void UpdatePerson(Identifier, Person, ListOfFieldNamesToUpdate)

  • স্বাক্ষরটি এতে পরিবর্তন করুন void UpdatePerson(Identifier, ListOfFieldValuePairs)

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

সমাধানগুলির কোনওটিই আমার কাছে সত্যই মার্জিত বলে মনে হয় না। অবশ্যই, এটি একটি সাধারণ সমস্যা, সুতরাং প্রত্যেকে কীভাবে ব্যবহার করবেন সেরা অনুশীলন সমাধান?


কেন ব্যক্তির পরিচয়কারী অংশ নয়? নতুনভাবে তৈরি হওয়া Personদৃষ্টান্তগুলির জন্য যা এখনও স্থির হয় না এবং ক্ষেত্রে যদি সনাক্তকারীকে দৃistence়তা ব্যবস্থার অংশ হিসাবে সিদ্ধান্ত নেওয়া হয় তবে কেবল এটি বাতিল করে দিন। উত্তর হিসাবে, জেপিএ একটি সংস্করণ নম্বর ব্যবহার করে; আপনি যদি 23 তম সংস্করণটি পড়েন, আপনি যখন আইটেমটি আপডেট করেন ডিবি-র সংস্করণটি 24 হয় তবে লেখাগুলি ব্যর্থ হয়।
এসজুয়ান 76

অনুমতি দিন এবং উভয় PUTএবং PATCHপদ্ধতি যোগাযোগ । ব্যবহার করার সময় PATCH, কেবল প্রেরণ কীগুলি প্রতিস্থাপন করা উচিত, PUTপুরো বস্তুটি প্রতিস্থাপন করা হয়।
লোড

উত্তর:


8

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

আপনার যদি ক্রিয়াকলাপ ট্র্যাকিংয়ের প্রয়োজনীয়তা থাকে। আপনার পৃথিবী আরও জটিল এবং আপনার কীভাবে সিআরইউডি ক্রিয়াকলাপ সম্পর্কিত তথ্য সংরক্ষণ করা যায় এবং সেগুলি কীভাবে বাধা দেওয়া যায় সেগুলি আপনাকে ডিজাইন করতে হবে। আপনার যদি এমন প্রয়োজনীয়তা না থাকে তবে আপনি সেই বিশ্বটিকে ডুবতে চান না।

পৃথক লেনদেন দ্বারা ওভাররাইডিং মান অনুসারে, আমি আশাবাদী এবং নিরাশাবাদী লকিংয়ের উপর গবেষণা করার পরামর্শ দেব । তারা এই সাধারণ পরিস্থিতি প্রশমিত করে:

  1. অবজেক্টটি ব্যবহারকারী 1 দ্বারা পঠিত
  2. অবজেক্টটি ব্যবহারকারী 2 দ্বারা পঠিত
  3. ব্যবহারকারী 1 দ্বারা লিখিত অবজেক্ট
  4. ব্যবহারকারী 2 দ্বারা লিখিত অবজেক্ট এবং ব্যবহারকারী 1 দ্বারা পরিবর্তনগুলি ওভাররাইট করা

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

খেয়াল করুন যে এটি লেখার আগে আপনাকে ডিবি থেকে আসল রেকর্ডটি পড়তে হবে (আশাবাদী লকিং সংস্করণ তুলনার জন্য), সুতরাং ডেল্টা লজিক প্রয়োগ (কেবলমাত্র পরিবর্তিত মান লিখুন) লেখার আগে অতিরিক্ত পঠিত ক্যোয়ারীর প্রয়োজন পড়বে না।

ডেল্টা লজিক স্থাপন করা ভোক্তাদের সাথে চুক্তির উপর নির্ভর করে, তবে লক্ষ্য করুন যে ভোক্তার পক্ষে সবচেয়ে সহজ ডেল্টার পরিবর্তে সম্পূর্ণ পেওলড তৈরি করা।


2

আমাদের কাজের পিএইচপি এপিআই রয়েছে। আপডেটের জন্য যদি কোনও ক্ষেত্রটি JSON অবজেক্টে না প্রেরণ করা হয় তবে এটি NULL এ সেট হয়ে যায়। তারপরে এটি স্টোরেজ পদ্ধতিতে সবকিছু পাস করে। সঞ্চিত পদ্ধতিটি ক্ষেত্র = IFNULL (ইনপুট, ক্ষেত্র) সহ প্রতিটি ক্ষেত্র আপডেট করার চেষ্টা করে। সুতরাং যদি 1 টি ক্ষেত্রটি JSON অবজেক্টে থাকে তবে কেবল সেই ক্ষেত্রটি আপডেট হয়। স্পষ্টভাবে একটি সেট ক্ষেত্র খালি করতে আমাদের = = 'ক্ষেত্র থাকতে হবে, ডিবি তারপরে খালি স্ট্রিং বা column কলামটির ডিফল্ট মান দিয়ে ক্ষেত্রটি আপডেট করে।


3
আপনি কীভাবে ইচ্ছাকৃতভাবে এমন একটি ক্ষেত্র নালায় সেট করবেন যা ইতিমধ্যে শূন্য নয়?
রবার্ট হারভে

সমস্ত ক্ষেত্র নাল নয়, তাই চার্ট ক্ষেত্রগুলি '' পেতে এবং সমস্ত পূর্ণসংখ্যার ক্ষেত্রটি 0 পায়
জ্যারেড বার্নাচি

1

ক্যোরি স্ট্রিংয়ে আপডেট হওয়া ক্ষেত্রগুলির তালিকা উল্লেখ করুন।

PUT /resource/:id?fields=name,address,dob Body { //resource body }

অনুরোধের বডি থেকে মডেলের সাথে মার্জ হওয়া সঞ্চিত ডেটা প্রয়োগ করুন:

private ResourceModel MergeResourceModel(ResourceModel original, ResourceModel updated, List<string> fields)
{
    var comparer = new FieldComparer();

    foreach (
            var item in
            typeof (ResourceModel).GetProperties()
                    .Where(p => p.CustomAttributes.All(a => a.AttributeType != typeof (JsonIgnoreAttribute))))
    {
        if (fields.Contains(item.Name, comparer))
        {
            var property = typeof (ResourceModel).GetProperty(item.Name);
            property.SetValue(original, property.GetValue(updated));
        }
    }

    return original;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.