إستعادة إستراتيجية إصدار الخدمة
فيرسيونينغ & بارا؛
يتم إصدار واجهة برمجة تطبيقات جيدة: يتم تنفيذ التغييرات والميزات الجديدة في الإصدارات الجديدة من واجهة برمجة التطبيقات بدلا من تغيير إصدار واحد فقط باستمرار. على عكس تطبيقات الويب، التي لديك السيطرة الكاملة على كل من جانب العميل ورمز من جانب الخادم، المقصود من واجهات برمجة التطبيقات لاستخدامها من قبل عملاء خارج سيطرتك. ولهذا السبب، ينبغي الحفاظ على التوافق الخلفي (بك) لواجهات برمجة التطبيقات كلما كان ذلك ممكنا. إذا كان التغيير الذي قد يكسر بريتيش كولومبيا أمرا ضروريا، فيجب إدخاله في الإصدار الجديد من واجهة برمجة التطبيقات (أبي)، وقم بتصعيد رقم الإصدار. يمكن للعملاء الحاليين الاستمرار في استخدام إصدار العمل القديم من واجهة برمجة التطبيقات؛ ويمكن للعملاء الجدد أو ترقية الحصول على وظائف جديدة في إصدار أبي الجديد.
نصيحة: ارجع إلى الإصدار الدلالي لمزيد من المعلومات حول تصميم أرقام إصدار واجهة برمجة التطبيقات.
إحدى الطرق الشائعة لتنفيذ إصدار واجهة برمجة التطبيقات هي تضمين رقم الإصدار في عناوين ورل لواجهة برمجة التطبيقات. على سبيل المثال، يقف المثال / v1 / المستخدمين لنقطة نهاية المستخدمين / إصدار أبي 1.
وهناك طريقة أخرى لنسخة أبي، التي اكتسبت زخما مؤخرا، هي وضع رقم الإصدار في رؤوس طلبات هتب. ويتم ذلك عادة من خلال رأس قبول:
كلا الطريقتين لها إيجابيات وسلبيات، وهناك الكثير من المناقشات حول كل نهج. في ما يلي ستظهر لك إستراتيجية عملية لإصدار أبي وهي مزيج من هاتين الطريقتين:
ضع كل إصدار رئيسي من تنفيذ واجهة برمجة التطبيقات في وحدة منفصلة يكون رقم تعريفها هو رقم الإصدار الرئيسي (على سبيل المثال، الإصدار 1، الإصدار 2). وبطبيعة الحال، ستحتوي عناوين ورل لواجهة برمجة التطبيقات على أرقام إصدارات رئيسية. ضمن كل إصدار رئيسي (وبالتالي ضمن الوحدة النمطية المقابلة)، استخدم رأس طلب قبول هتب لتحديد رقم الإصدار الثانوي وكتابة التعليمات البرمجية الشرطية للرد على الإصدارات الثانوية وفقا لذلك.
لكل وحدة تخدم نسخة رئيسية، يجب أن تتضمن وحدة الموارد وفئات تحكم التي تخدم هذا الإصدار المحدد. لتحسين مسؤولية التعليمات البرمجية منفصلة، قد تحتفظ مجموعة مشتركة من الموارد الأساسية وفئات وحدة تحكم، وفئة فرعية لهم في كل وحدة نمطية إصدار فردي. ضمن الفئات الفرعية، تنفيذ التعليمات البرمجية ملموسة مثل نموذج :: الحقول ().
قد يتم تنظيم الشفرة كما يلي:
ستبدو تهيئة التطبيق كما يلي:
نتيجة رمز أعلاه، مثال / V1 / المستخدمين سيعود قائمة المستخدمين في الإصدار 1، في حين أن المثال / V2 / المستخدمين سيعودون الإصدار 2 المستخدمين.
بفضل وحدات، رمز للإصدارات الرئيسية المختلفة يمكن أن تكون معزولة بشكل جيد. ولكن الوحدات تجعل من الممكن إعادة استخدام التعليمات البرمجية عبر الوحدات عبر الطبقات الأساسية المشتركة والموارد المشتركة الأخرى.
للتعامل مع أرقام الإصدارات الثانوية، يمكنك الاستفادة من ميزة التفاوض على المحتوى التي يوفرها سلوك كونتنتنيغوتاتور. سيقوم سلوك كونتنتيغوتاتور بتعيين الخاصية يي \ ويب \ ريسبونز :: $ أسيبتبارامز عند تحديد نوع المحتوى الذي سيتم دعمه.
على سبيل المثال، إذا تم إرسال طلب مع رأس هتب أسيبت: أبليكاتيون / جسون؛ فيرسيون = v1، أفتر كونتنت نيغوتياتيون، يي \ ويب \ ريسبونز :: $ أسيبتبارامز سيحتوي على القيمة ['فيرسيون' = & غ؛ 'v1'].
استنادا إلى معلومات الإصدار في أسيبتبارامز، يمكنك كتابة التعليمات البرمجية الشرطية في أماكن مثل الإجراءات، وفئات الموارد، المسلسلات، وما إلى ذلك لتوفير الوظائف المناسبة.
بما أن إصدارات بسيطة بحكم التعريف تتطلب الحفاظ على التوافق الخلفي، نأمل أنه لن يكون هناك العديد من الشيكات النسخة في التعليمات البرمجية. وإلا، فمن المحتمل أنك قد تحتاج إلى إنشاء إصدار رئيسي جديد.
الصفحة التي تم إنشاؤها في السبت، 30 ديسمبر 2017 02:46:49 +0100.
ريستفول أبي فيرسيونينغ ستراتيجيس.
قبل أن تحصل بعيدا جدا في المكسرات والمسامير من أسب ويب أبي الخاص بك، أو أي أبي أخرى، يجب عليك قضاء بعض الوقت في التفكير كيف أنت ذاهب إلى إصدار التطبيق. حتما، سوف أعرض كسر التغييرات التي سوف تحتاج إلى أن تدار بطريقة أو بأخرى. استراتيجية جيدة الإصدار يسمح لك لإدخال هذه التغييرات كسر دون كسر التطبيق فورا بالنسبة لك المستهلكين أبي. وينبغي أن تتاح لهم الفرصة للاشتراك في النسخة الجديدة من أبي وعدم إجبارهم على الترقية فورا خوفا من وجود كسر التطبيق إذا كانوا لا & # 8217؛ ر. هذا يسمح لهم أن يقرر ما إذا كان من المنطقي للترقية على الإطلاق، ويعطيهم الوقت لميزانية (الموارد والمال) للترقية وجدولة تنفيذ الترقية الفعلية.
هناك عدة طرق لإصدار أبي، ولكل منها مزاياها وعيوبها. ما تعلمته في القيام بذلك لفترة من الوقت الآن هو أنه بغض النظر عن الطريقة التي تذهب، شخص ما سيكون لديه مشكلة مع ذلك. إما أنه من الصعب جدا أن تستهلك، أكاديمية جدا، من السهل جدا للحصول على خطأ أو عدد لا يحصى من الأشياء. نصيحتي هي النظر في جميع الخيارات واختيار واحد على أساس الاحتياجات الخاصة بك & # 8211؛ والمبلغ المتوقع للتغيير، ومكياج من المستهلكين، وسهولة المطلوب من الاختبار أو أي خصائص أخرى ذات أهمية خاصة ل أبي الخاص بك.
في هذا المنصب، وسوف تصف حفنة من استراتيجيات الإصدار الذي أنا & # 8217؛ تأتي عبر وإعطاء بلدي تأخذ على مزاياها و ديسادفاتاجيس. أنا & # 8217؛ ليرة لبنانية ترك الأمر متروك لك أن تقرر ما هو أفضل لسيناريو الخاص بك.
إصدار ورل.
في هذه الاستراتيجية، يمكنك ببساطة تضمين إصدار واجهة برمجة التطبيقات في عنوان ورل لمورد ما. وبهذه الطريقة، عندما تريد الوصول إلى إصدار مختلف من واجهة برمجة التطبيقات أو المورد، يمكنك ببساطة تغيير رقم الإصدار في عنوان ورل. هذا من السهل جدا القيام به يدويا وبسيطة لتنفيذ برمجيا. يطلب المتصل صراحة إصدارا من واجهة برمجة التطبيقات من خلال تضمين هذه المعلومات في عنوان ورل للطلب.
هناك مشكلة واضحة مع هذه الاستراتيجية على الرغم من & # 8211؛ يجب أن يمثل عنوان ورل الكيان ويجب ألا يتغير بسبب إصدار. من المفترض أن يكون عنوان ورل هو عنوان & # 8220؛ & # 8221؛ من هذا المورد وعنوان & # 8220؛ & # 8221؛ لا ينبغي تغييره لأن رقم الإصدار قد تم صدمه. وأنا أتفق مع ذلك إلى حد ما. يجب أن يحدد عنوان ورل المورد الذي أمتلكه، وليس إصدار هذا المورد. أن يقال، أنا لا & # 8217؛ ر بالضرورة نعتقد أن هذا هو صفقة صفقة. عادة ما أختار إستراتيجية الإصدار هذه لأنها واضحة جدا وسهلة الإدارة عن طريق إستراتيجية التفرع والنشر، كما أنها لا تقدم تعقيدا في شفرة المصدر ومن السهل اختبارها وإرسال الروابط التي يمكن للآخرين النقر عليها فقط.
كيريسترينغ المعلمة.
هذه الاستراتيجية مشابهة جدا لاستراتيجية إصدار عناوين ورل من حيث أنها تتطلب أن يتضمن المتصل رقم الإصدار في عنوان ورل الخاص بالمورد. الفرق هو أن رقم الإصدار يتم تضمينه كمعلمة سلسلة الاستعلام بدلا من في مسار ورل. وهذا يعني أن شيئا في الخلفية يحتاج إلى تفسير رقم الإصدار هذا وتوجيه الطلب إلى الإصدار المناسب من واجهة برمجة التطبيقات لمعالجته. ويمكن القيام بذلك إما برمجيا عبر استخدام أحد بوابات أبي أتحدث عن أدناه. هذا يجعل من الصعب أكثر قليلا لتنفيذ برمجيا، لكنه يحتفظ نفس المزايا التي لديها استراتيجية الإصدار ورل.
أنا لا & # 8217؛ عادة ما تختار هذه الاستراتيجية لأن لدي نفس الأشياء الفلسفية لذلك أن أفعل لنسخة ورل وأنه هو أكثر من ذلك بكثير المشاركة لتنفيذ على الخلفية. عادة، هذا يعني كتابة بعض التعليمات البرمجية التي تستخدم رقم الإصدار لتوجيهها إلى وحدة تحكم أو إجراء مناسب. إذا كنت تريد تضمين الإصدار في عنوان ورل للموارد، فأفضل استخدام إستراتيجية إصدار عناوين ورل أعلاه وإدارة توجيه الطلب إلى إصدار معين باستخدام استراتيجيتي التفرع والنشر.
رأس طلب مخصص.
تتطلب هذه الاستراتيجية أن يتضمن المتصل مخصص & # 8220؛ أبي-فيرسيون & # 8221؛ رأس مع كل طلب لإخبار الملقم ما إصدار أبي انهم يريدون الوصول. على عكس الاستراتيجيات السابقة، فإن هذا التنفيذ لا يؤثر على المورد & # 8217؛ s & # 8220؛ أدرس & # 8221؛ & # 8211؛ يمكنك الوصول إلى مورد باستخدام عنوان ورل نفسه في جميع إصدارات واجهة برمجة التطبيقات. وبدلا من ذلك، يمكنك جعل جزء الإصدار من البيانات الوصفية التي يتم إرسالها مع الطلب وتعتمد على الخادم الخلفي لتوجيه الطلب بشكل مناسب. المشكلة مع رؤوس الطلبات هي أنها ليست حقا وسيلة دلالية لوصف المورد. قد يجادل البعض بأن مواصفات هتب توفر آليات أخرى لوصف كيف نريد أن يكون المورد ممثلا ولا ينبغي أن نعيد إنتاجه.
مشكلة واحدة مع هذا النهج هو أنه، مثل المعلمة الاستعلام سلسلة الاستعلام، فإنه يتطلب أن الواجهة الخلفية بطريقة أو بأخرى تفسر القيمة وتوجيه الطلب إلى وحدة تحكم أو إجراء مناسب. هناك العديد من الطرق التي تم تأسيسها باستخدام قابلية توسع أبي ويب أبي. المشكلة بالنسبة لي هي، في النهاية، أنها تنطوي على الحفاظ على إصدارات مختلفة من وحدة تحكم / العمل جنبا إلى جنب في التعليمات البرمجية.
بالإضافة إلى مشكلات الشفرة، فإن الروابط إلى واجهة برمجة التطبيقات مع هذا النوع من إستراتيجية الإصدار لا تتم مشاركتها أو اختبارها بسهولة. يجب عليك إنشاء طلب بعناية باستخدام رأس النسخة المخصصة للوصول إلى إصدار محدد من واجهة برمجة التطبيقات. وهذا يعني أنه إذا أردت مشاركة رابط إلى نقطة نهاية واجهة برمجة التطبيقات، يجب تضمين بعض الإرشادات حول كيفية إنشاء الطلب وربما بعض لقطات الشاشة حول كيفية القيام باستخدام أداة مثل بوستمان.
قبول الرأس.
هذه الاستراتيجية مشابهة جدا لاستراتيجية رأس مخصص الموضحة قبل إلا أنه يستخدم بروتوكول هتب & # 8217؛ s المضمنة في رأس قبول لوصف إصدار واجهة برمجة التطبيقات التي يريد المتصل الوصول إليها. والفكرة هي أن مواصفات هتب توفر بالفعل هذا الرأس لوصف جوانب أخرى من النتائج المتوقعة وينبغي أن يكون الإصدار مجرد عنصر آخر من هذا.
تماما مثل استراتيجية رأس مخصص، هناك عدة طرق لتنفيذ هذا على الخلفية. تشارك هذه الاستراتيجية نفس العيوب التي أدرجتها لاستراتيجية رأس مخصص أيضا.
إدارة أبي.
هناك العديد من العروض إدارة أبي هناك أن نقدم مجموعة واسعة من الميزات التي هي مفيدة لإدارة واجهات برمجة التطبيقات. بعض من هذه التطبيقات إدارة قوية حقا وتسمح لك للقيام طن من العمليات المتطورة حقا على أعلى من واجهات برمجة التطبيقات الخاصة بك. كل هذه التطبيقات بمثابة بوابة بين المستهلكين أبي و أبي الفعلية التي خدمة الطلب واردة. يوفر بعضها القدرة على التوجيه إلى إصدار من واجهة برمجة التطبيقات بناء على خصائص مختلفة للطلب الوارد. هذا، جنبا إلى جنب مع الميزات الأخرى التي تقدمها، تجعل تطبيقات إدارة واجهة برمجة التطبيقات خيارا جذابا جدا لإصدار أبي & # 8211؛ خاصة إذا كنت تبحث في القيام أيضا أشياء مثل اختناق الوصول، تشونكينغ النتائج، تلقائيا هتبس دونشيفتنغ وتوليد وإدارة مفاتيح أبي. في ما يلي بعض موفري إدارة واجهة برمجة التطبيقات التي يمكنك التفكير فيها.
نجينكس & # 8211؛ يسمح لك بإجراء عمليات إعادة كتابة عناوين ورل استنادا إلى جوانب مختلفة من الطلب الوارد. على سبيل المثال، يمكنك إعادة كتابة الطلب إلى إصدار مختلف من أبي استنادا إلى عنوان إب المتصلين.
أكانا (سابقا سوا سوفتوار) & # 8211؛ يمكنك توجيه الطلبات بناء على محتوى الرسالة والرؤوس والهوية وعوامل أخرى.
كما رأيت، هناك الكثير من الخيارات لإصدار أسب ويب أبي. كل واحد لديه مزايا وأوجه القصور. في النهاية، ما يهم أكثر هو التنفيذ الذي تذهب معه. وبدلا من ذلك، لقد نفذت بعض إستراتيجية الإصدار في واجهة برمجة التطبيقات. دون واحد، وسوف يسبب حتما قضايا المستهلكين الخاص بك عند إدخال نوع من كسر التغيير. فمن الأفضل أن تنفق قدرا صغيرا من الوقت في وقت مبكر تنفيذ استراتيجية الإصدار من أن تضطر إلى التعامل مع صعبة الترقية التدريجي والعملاء الغاضبين في وقت لاحق.
من جهتي، لقد اخترت دائما إستراتيجية إصدار عناوين ورل. فإنه لا يفعل تشويش رمز مع منطق الإصدار، ويمكن التعامل معها بسهولة من خلال المتفرعة واستراتيجيات النشر. في معظم الأحيان، تفاصيل التنفيذ هي من طريقة مطور البرامج & # 8217؛ s.
مقالات ذات صلة:
تذييل المشاركة الذي تم إنشاؤه تلقائيا من خلال إضافة إضافة تذييل المشاركة ل وردبريس.
أحب نظرة عامة على مستوى عال. مليء بالمعلومات! شكر.
إصدار خدمات ويب ريست.
من الصعب إدارة التغييرات في واجهات برمجة التطبيقات. هذا ليس من المستغرب لأي شخص من أي وقت مضى الحفاظ على أبي من أي نوع. خدمات الويب، كونها حالة خاصة من أبي، هي عرضة للكثير من الصعوبات حول الإصدار مثل أنواع أخرى من واجهات برمجة التطبيقات. بالنسبة إلى خدمات ويب نمط ريست القائمة على هتب، يمكن الجمع بين الموارد وتفاوض المحتوى للتخفيف من معظم المشكلات المحيطة بإصدار أبي.
اسمحوا & # 8217؛ افترض أن لديك خدمة ويب ريست / هتب يحتوي على بعض موارد الحساب. لنفترض أنك تستطيع تقديم طلب من هذا القبيل:
أولا، ربما لاحظت أن مثالي يستخدم نوع الوسائط مايم البائع لوصف التمثيل. استخدام نوع الوسائط مايم أكثر عامة مثل تطبيق / شمل هو أكثر شيوعا، على الأقل في تجربتي. استخدام أنواع الوسائط العامة هو قانوني تماما ولكن قليلا سخيفة. أنت لا تطلب حقا أي مستند شمل قديم، بل مستند شمل يحتوي على مخطط محدد تماما. وبصرف النظر عن بلدي الهتافات المثالية، وذلك باستخدام نوع وسائل الإعلام محددة لديها بعض الفوائد العملية القوية التي هي في صميم هذا المنصب.
عكس التغييرات المتوافقة.
وغالبا ما يتعين إجراء تغييرات لفضح السلوك الجديد للنظام الذي لا يؤثر سلبا على العملاء المنفذين بشكل صحيح. لنفترض مثلا أنك تريد بدء تتبع عنوان البريد الإلكتروني للحسابات. إذا كانت وثائق التطبيق / vnd. mycompany. myapp + شمل واضحة أن العناصر التي لم يتم التعرف عليها يجب تجاهلها يمكنك ببساطة إضافة عنصر بريد إلكتروني إلى تمثيل الحساب.
أي عميل تم إنشاؤه قبل إضافة عنصر البريد الإلكتروني سيتجاهل ببساطة وجوده. تم حل المشكلة.
تغييرات غير متوافقة.
لسوء الحظ، لا يمكن تنفيذ جميع التغييرات بطريقة متوافقة مع الوراء. على سبيل المثال، بعد شهرين من إضافة البريد الإلكتروني إلى حسابات فريق المبيعات يوقع صفقة ل 1 بازيليون دولار. ولكن العميل الجديد يطالب بأن يسمح لكل حساب بأن يكون لديه أكثر من عنوان بريد إلكتروني واحد. بعد التفكير لفترة من الوقت، عليك أن تقرر أن أفضل طريقة لفضح هذا هو عن طريق تغيير تمثيل الحساب على النحو التالي.
وهذا، بطبيعة الحال، سوف كسر أي العملاء الذين يتوقعون الشكل القديم & # 8211؛ جميلة جدا كل منهم. هذا هو المكان الذي يمكننا أن نجعل المحتوى التفاوض على تحمل. يمكنك ببساطة تحديد نوع جديد من الوسائط & # 8211؛ ساي أبليكاتيون / vnd. mycompany. myapp-v2 + شمل & # 8211؛ وربط شكل جديد متعدد البريد الإلكتروني معها. يمكن للعملاء ثم طلب أي شكل تريد. لا يعرف العملاء الأكبر سنا نوع الوسائط الجديدة حتى يتمكنوا من تقديم تنسيق البريد الإلكتروني القديم القديم.
عملاء جدد يعرفون نوع وسائل الإعلام الجديدة حتى يتمكنوا من الوصول إلى وظائف جديدة.
الجميع يحصل على ما يحتاجون إليه. سهلة كما فطيرة.
النهج البديلة.
يبدو أن النهج الأكثر شيوعا لإصدار واجهات خدمة ويب ريست / هتب اليوم هو تشويه أوريس عن طريق إدراج نسخة. فمثلا،
أنا حقا أكره هذا النهج لأنه يعني ضمنا أن حساب في نسخة واحدة من أبي هو حقا مورد مختلف عن الحساب في إصدار مختلف من أبي.
كما أنها تجبر العملاء على اختيار سيئة، إما دعم إصدارات متعددة من أبي في وقت واحد أو كسر واحد من القيود الأساسية من ريست. على سبيل المثال، لنفترض وجود عميل لواجهة برمجة التطبيقات v1 التي تحفظ المراجع (عناوين ورل التي تتضمن مؤشر الإصدار) إلى الحسابات. بعض الوقت في وقت لاحق يتم تحديث العميل لدعم الإصدار الجديد من أبي. في هذه الحالة يمكن للعميل دعم كلا الإصدارين أبي في وقت واحد لأن كافة أوريس المخزنة سابقا تشير في الإصدار القديم من أبي أو أنه يجب مونغ كافة أوريس التي تم تخزينها إلى نقطة في أبي الجديد. مونغينغ كل أوريس يكسر هاتيواس قيد ريست ودعم إصدارات متعددة من أبي هو كابوس الصيانة.
استنتاج.
تغييرات على واجهات خدمة ويب ريست / هتب تأتي ثلاث نكهات الأساسية، والتغييرات على الخصائص المرتبطة نوع من الموارد، والإضافات من أنواع جديدة من الموارد وإهمال أنواع عفا عليها الزمن من الموارد. إذا كنت تتبع القيود هاتيواس من ريست النهج الموصوفة هنا يمكن استخدامها للتعامل بأمان مع جميع السيناريوهات الثلاثة.
هذا النهج يؤدي إلى أنواع الوسائط التي يتم إنشاؤها، ولكن أنواع وسائل الإعلام رخيصة حتى نتمكن من & # 8211؛ ويجب أن & # 8211؛ لدينا ما نحتاج إليه. تستخدم بشكل صحيح، يمكن استخدام التفاوض المحتوى لحل المشاكل المتعلقة بإصدار واجهة خدمة ويب ريست / هتب.
الوظائف ذات الصلة.
إذا كنت مهتما بخدمة إصدار ريست / هتب، تأكد من عدم تفويت بقية السلسلة.
69 تعليقات على & لدكو؛ فيرسيونينغ ريست ويب سيرفيسز & رديقو؛
[& # 8230؛] بيتر ويليامز & # 8211؛ فيرسيونينغ ريست ويب سيرفيسز & # 8211؛ وهو مقال قديم ولكنه بديل لطيف للتعامل مع إصدار واجهة برمجة التطبيقات [& # 8230؛]
كيف يعمل هذا مع واجهات برمجة التطبيقات للقراءة / الكتابة؟ إذا أضفت سمة كتغيير غير قابل للكسر، لذا لا تغير نوع الوسائط، فسيستمر العملاء القدامى في بيانات بوت و بوست يفتقدون السمة الجديدة. يمكنني إصلاح هذا على الخادم عن طريق تعيين السمة إلى قيمة افتراضية أو ترك القيمة الحالية للسمة دون تغيير، ولكن هل يسبب مشاكل مع مخابئ، والتي قد تحل محل النسخة المخبأة مع التحديث الجزئي؟ إيسن & # 8217؛ t هذا بشكل فعال نفس المشكلة كما تفعل التحديثات الجزئية مع بوت؟
السمة الهامة من بوت هو أنه يجب أن يكون إيمبوتنت، وليس أنها لا تسمح بتحديثات جزئية. ومن الشائع جدا للجسم من طلب بوت لا تشمل كل الممتلكات من المورد. على سبيل المثال، آخر حقول الطابع الزمني المحدثة.
أنا هذه الحالة سيكون وضع إديمبوتنت. العميل القديم لا يعرف ولا يهتم بهذه الخاصية الجديدة، لذلك لا يهتم حقا كيف يتم التعامل مع قيم & # 8217؛ s. أي من الطرق التي ذكرتها للتعامل مع قيمة الممتلكات المفقودة سيكون على ما يرام.
سوف مخابئ رعاية أنفسهم. مخابئ دون & # 8217؛ ر استخدام الجسم من بوت. أنها مجرد إبطال تمثيلات المخزنة مؤقتا سابقا لهذا المورد. وهذا يعني أن طلب جيت التالي لهذا المورد سيذهب إلى الخادم وسيتم الرد مؤقتا على رد & # 8217 ؛. على افتراض يتم إعادة الممتلكات الجديدة دائما مخابئ سوف تبقى حتى الآن.
تتحدث عن استخدام رأس أسيبت & # 8211؛ هل ينطبق الشيء نفسه على نوع المحتوى ل بوست / بوت؟ يتكون أبي تا من المدخلات والمخرجات.
ينطبق ذلك تماما على نوع محتوى طلبات بوست و بوت. وكما أن حقل رأس قبول طلبات جيت يسمح للخادم بإعطاء العميل التمثيل المحدد الذي يتطلبه، فإن حقل رأس نوع المحتوى لطلبات بوست و بوت يعطي الملقم المعلومات التي يحتاجها لتفسير مجموعة البيانات بشكل صحيح من قبل العميل.
في تعليقاتك هنا وعلى رد & # 8220؛ على جان & # 8221؛ مشاركة تشير إلى أنك لا تفكر في قبول الإضافة مثل & # 8220؛ المستوى & # 8221؛ أو & # 8220؛ فيرسيون & # 8221؛ هو مناسب للإشارة إلى التغييرات غير المتوافقة (أي النسخة الرئيسية). ولكن قراءتي للأمثلة في مواصفات هتب والوثائق التاريخية ذات الصلة يقودني إلى الاعتقاد بأن هذا هو الغرض المقصود بالضبط. جميع استخدامات & # 8220؛ ليفيل & # 8221؛ يبدو أن التمديد يرجع تاريخيا إلى & # 8220؛ تكست / هتمل & # 8221؛ (هتمل 2، هتمل 3، إلخ.) توضح هذه الصفحة (W3 / ماركوب / تابل-ديبلويمنت) المؤرخة في عام 1995 بوضوح استخدام & # 8220؛ تكست / هتمل؛ مستوى = 3 & # 8221؛ نوع الوسائط للإشارة إلى عملاء هتمل 2 فقط أنهم لم يفهموا الترميز ويجب ألا يحاولوا ذلك.
ومع ذلك، هذا هو إلى حد كبير ممارسة أكاديمية. في غياب تعريف محدد يبدو أن أنواع الوسائط يجب أن تعامل على أنها سلاسل مبهمة، لذلك & # 8220؛ تطبيق / vnd. mycompany. myapp-v2 + شمل & # 8221؛ و & # 8220؛ أبليكاتيون / vnd. mycompany. myapp + شمل؛ مستوى = 2 & # 8221؛ وكلاهما يخدم نفس الغرض. وبما أنه يبدو أن هناك إجماعا على أن الأول هو الشكل الأفضل لاستخدام I & # 8217؛ ليرة لبنانية بهذه الطريقة، أنا فقط لا & # 8217؛ ر نرى أي سبب أن التنسيق في وقت لاحق هو أي أقل صالحة. وفي الواقع باستخدام & # 8220؛ المستوى & # 8221؛ تمديد للإصدار طفيفة يبدو مضادة للسابقة التاريخية، ولكن (إمهو) مقبولة وغير ضارة إذا ما استخدمت على وقت مايم مخصص.
إنترودكتيون سيميراديولوغي يستخدم أسلوب ريست المعماري لفضح وظيفة التكامل. تصف هذه الوثيقة أنواع الوسائط والتمثيلات المستخدمة من قبل واجهة برمجة التطبيقات. الجمهور المستهدف هذه الوثيقة ليست مقدمة ل ريست & # 8230؛ & # 8230 ؛.
[& # 8230؛] بالنسبة لإصدار أبي، حسنا، هناك نوع من أفكار المفهوم: فيرسيونينغ ريست ويب سيرفيسز [& # 8230؛]
[& # 8230؛] فيرسيونينغ ريست ويب سيرفيسز [& # 8230؛]
أفكار للتدريب الصيفي 2018 ريستفول داتا & # 8230؛
ما هي بعض الإستراتيجيات لإصدار واجهات برمجة التطبيقات؟ & # 8230؛
إذا كنت بحاجة إلى نشر وتوثيق التعديلات الجذرية على واجهات برمجة التطبيقات الخاصة بك مرة واحدة كل بضع سنوات ولكن تحتاج إلى أن أوصي الإصدار الصريح في جذر المسار الخاص بك. قد يكون مثال ريست هو / أبي / v2 / ريسورس / 123 / سوب / القيام بذلك على مستوى النطاق الفرعي قد يكون & # 8230؛
مرحبا هناك إلى كل واحد، انها & # 8217؛ ق حقا لطيفة بالنسبة لي لزيارة هذا الموقع، فإنه يحتوي على معلومات لا تقدر بثمن.
ويبسيرفيس فيرسيونينغ بوليسي روابط إلى معلومات حول ويبسيرفيس فيرسيونينغ & # 8230؛
[& # 8230؛] لا يزال في طور الإعداد. كما لا يزال هناك الكثير من الشركات التي لا تزال تستخدم إدي الحق؟ أنا حاليا تعمل على مشروع يتطلب نشر وقراءة الاستجابة عبر الإنترنت باستخدام شمل. I & # 039؛ m & # 8230؛ (التثاؤب)، لديك موقع المستخدم جعل التحديدات و بوست التي مرة أخرى كما شمل القديمة عادي، والحصول على رد آخر [& # 8230؛]
التقنيات الشائعة ل ويبسرفيس فيرسيونينغ # فهم أنواع التغيير # استخدام نهج الربط المرن ## استخدام غير مباشر للحصول على نقطة نهاية خدمة (استخدام أودي كسجل خدمة فيرسيونوار) ## تجنب الافتراضات أن أي جانب من جوانب الخدمة، & # 8230؛ & # 8230؛
[& # 8230؛] من الإصدار أبي مع أنواع مايم، استخدمنا رأس X-غوالا-أبي-فيرسيون منفصل، مع التخلف عن أحدث إصدار إذا كان [& # 8230؛]
[& # 8230؛] версиями أبي - это разные ресурсы. ترجمة: التطبيق / vnd. mycompany. myapp-v2 + شمل. Концептуально это мне [& # 8230؛]
مقدمة تبو يجب أن تكون صفحات تعريف واجهة برمجة التطبيقات b & # 8230؛
تعليق الملاحة.
التعليقات مغلقة.
آخر الملاحة.
اسمي بيتر ويليامز. أنا الأب والبرمجيات المطور. (أفعل بعض الأشياء الأخرى، بطبيعة الحال، ولكن الأسرة والبرمجيات هي ما أنا أكثر عاطفي حول.) هذا بلوق هو في المقام الأول المكان الذي يمكن أن رانت دون خداع الكثير من الناس، ولكن أحيانا تسجيل الأشياء التي تهم عائلتي هنا.
لا تحتاج واجهات برمجة تطبيقات ريست إلى إستراتيجية إصدار & # 8211؛ فإنها تحتاج إلى استراتيجية التغيير.
التغيير في أبي أمر لا مفر منه مع المعرفة والخبرة الخاصة بك من نظام يحسن. إدارة تأثير هذا التغيير يمكن أن يكون تحديا كبيرا عندما يهدد بكسر التكامل العملاء الحالية.
غالبا ما يحاول المطورون اتخاذ قرار بشأن استراتيجية الإصدار بمجرد بدء العمل على واجهة برمجة التطبيقات. هذا أمر مفهوم ولكن ليس دائما أذكى طريقة للنظر في مشكلة إدارة التغيير. براندون بييرز لخص هذا عن طريق الاقتراض جيمي زاونسكي & # 8217؛ ق حفر في التعبيرات العادية:
بعض الناس، عندما واجهوا مشكلة، أعتقد & # 8220؛ وأنا أعلم، وأنا & # 8217؛ ليرة لبنانية استخدام الإصدار. & # 8221؛ الآن لديهم 2.1.0 المشاكل.
كيف يمكنك تحرير الموارد في ريست؟
ريست لا تنص على أي إصدار محدد ولكن النهج الأكثر شيوعا تقع في ثلاثة مخيمات: وضعه على عنوان أوري، باستخدام رأس طلب مخصص أو إضافته إلى رأس قبول هتب.
استخدام أوري هو النهج الأكثر مباشرة على الرغم من أنه يزعج ريست يدافعون الذين يصرون على أن أوري يجب أن تشير إلى مورد فريد من نوعه. ويضمن لك أيضا لكسر تكامل العميل عندما يتم تحديث إصدار مهما كنت تستثمر بكثافة في التوجيه الإبداعي والاتصال العميل.
يسمح لك رأس مخصص بالحفاظ على عناوين ورل الخاصة بك بين الإصدارات على الرغم من أنها مكررة بشكل فعال لسلوك التفاوض على المحتوى الذي يتم تنفيذه بواسطة رأس أسيبت الموجود. يمكن للعميل استخدام هذا الرأس لإرسال قائمة الإصدارات المعتمدة أثناء استجابة الخادم بالإصدار المستخدم في رأس نوع المحتوى.
قد تسمح لك مفاوضات المحتوى بالحفاظ على مجموعة نظيفة من عناوين ورل ولكن لا يزال يتعين عليك التعامل مع تعقيد خدمة إصدارات مختلفة من المحتوى في مكان ما. هذا العبء يميل إلى أن يتم نقل كومة إلى وحدات تحكم أبي الخاصة بك التي تصبح مسؤولة عن معرفة أي إصدار من الموارد لإرسالها. والنتيجة النهائية تميل إلى أن تكون أبي أكثر تعقيدا كما يجب على العملاء أن يعرف أي رؤوس لتحديد قبل طلب مورد.
رقم الإصدار ليس هو المشكلة.
نظرا للطبيعة المثيرة للجدل من ريست، عليك أن تكون دائما خاطئة في عيون شخص بغض النظر عن النهج الذي كنت تأخذ. النقطة هي أن النسخة ترقيم نفسها هي الرنجة الحمراء.
التحدي الحقيقي هنا هو إدارة قاعدة التعليمات البرمجية التي يمكن أن تصل إلى إصدارات متعددة من الموارد. إذا حافظت على كافة الإصدارات في نفس قاعدة التعليمات البرمجية، تصبح الإصدارات الأقدم عرضة للتغيرات غير المتوقعة. إذا قمت بفصل قواعد التعليمات البرمجية ثم تتصاعد النفقات التشغيلية والدعم. في كلتا الحالتين، سخام الشفرات وزيادة التعقيد هي نتيجة حتمية.
إن اتباع نهج صارم في إصدار الإصدارات يمنحك اليقين الذي تشتد الحاجة إليه بشأن العقد ولكنه يميل إلى تقويض قدرة النظام على التغيير. يمكن أن يصبح الإصدار عائقا أمام التحسين حيث تتم مقاومة أي متطلبات تؤدي إلى تغييرات في الإصدار. لقد رأيت واجهات برمجة التطبيقات مع سياسات إصدار صارم عالقة على نفس الإصدار لسنوات بسبب المخاوف المشروعة على مقدار العمل والمخاطر التي ينطوي عليها التغيير.
ما هو البديل للإصدار؟
يجب أن تتناول إستراتيجية إصدار متماسكة كيفية إدارة التغيير في أبي مع توفير عقد مستقر للعملاء. وهذا لا يجب أن يتضمن إصدار إصدارات جديدة استجابة للتغييرات.
ويتمثل أحد النهج في بناء إمكانية التغيير من خلال توفير التوافق على الوراء في تغييرات واجهة برمجة التطبيقات. هذا النهج ينطوي على مخاطر كبيرة حيث لا يمكنك التأكد من أن التغيير لن كسر العملاء الحاليين حتى مع اختبار الانحدار الشامل.
يمكنك حتى اتخاذ التوافق الوراء خطوة أبعد من خلال إضافة ميزات مثل المعلمات الاختيارية وخصائص البدل التي تتوقع التغييرات المستقبلية. هذا النوع من "التوافق الآجل" يميل إلى إنتاج عقد خشن يضع عبئا كبيرا من المصادقة على العميل. والنتيجة النهائية هي في كثير من الأحيان مجموعة فوضوي من رموز التبديل والرموز المطلوبة لكل مكالمة.
يقترح مبدأ أوبين \ كلوسيد برتراند ماير أن الكيانات البرمجية يجب أن تكون "مفتوحة للتمديد، لكنها مغلقة للتغيير". عند تطبيقه على واجهات برمجة التطبيقات، فإن النتيجة تعني أنه يمكنك زيادة مواردك ولكن لا يتم تغييرها.
ويمكن أن يوفر هذا النهج اليقين من إصدار أكثر صرامة دون مخاطر الانحدار التي ينطوي عليها التوافق إلى الوراء. زيادة لا تخلو من مشاكلها على الرغم من أنها يمكن أن تؤدي إلى العقود المتضخمة. وبدون انضباط دقيق يمكن أن تصبح أبي متناثرة مع أساليب مكررة أو الموارد التي توفر عدة طرق مختلفة قليلا لتحقيق الشيء نفسه.
يمكنك مشاركة المسؤولية؟
يمكنك أن تفعل المزيد لتقاسم عبء التغيير بين أبي والعميل. قانون بوستيل، الذي يشار إليه غالبا بمبدأ المتانة، ينص على أنه يجب أن تكون "ليبراليا في ما تقبله وتحافظ عليه في ما ترسله". من حيث أبيس هذا ينطوي على التسامح معينة في الخدمات الاستهلاكية.
على سبيل المثال، يمكن أن تكون تقنيات التسلسل الصارمة غير متسامحة دون داع للتغيير. وينبغي أن يكون القارئ الأكثر تسامحا معنيا فقط بالبيانات التي يحتاج إليها ويتجاهل كل جزء آخر من الاستجابة. وهذا يعني أن غالبية التغييرات من غير المرجح أن تكسر التكامل.
وهناك نهج آخر يمكن للمستهلك أن يعلن البيانات التي يهمه كجزء من الطلب. ولا يحدد نمط العقد الذي يحركه المستهلك النموذج الذي يجب أن تتخذه هذه التأكيدات من قبل المستهلكين، ولكن يمكن أن يسمح التنفيذ لواجهة برمجة التطبيقات باكتشاف متى يكون الطلب غير محدث.
ولسوء الحظ، لا يمكن تطبيق هذه النهج إلا على مجتمعات الخدمات المغلقة نسبيا. نادرا ما يكون واجهات برمجة التطبيقات التي تواجه الجمهور ترفا في أن تكون قادرة على تملي أسلوب التكامل العميل. يتكون العقد الوحيد القابل للتطبيق بين الخدمة والعميل من البيانات والبروتوكول.
هذا هو السبب في الانضباط الحذر هو في صميم أي استراتيجية تغيير معقولة. أبي جيدة لا تأتي إلى حيز الوجود عن طريق الصدفة. يجب أن تكون برعاية. وأيا كانت الطريقة التي تتخذها لإدارة التغيير، فستحتاج إلى حكم متسق ونشط على العقد المتطور.
أنا مهندس معماري مقره لندن الذي أمضى أكثر من عشرين عاما التنمية الرائدة عبر المبتدئة والوكالات الرقمية، ومكاتب البرمجيات والشركات. على مر السنين لقد بنيت الكثير من الاشياء بما في ذلك المواقع والخدمات على شبكة الإنترنت، وتطبيقات شاشات متعددة، تكامل النظم والوسيطة.
تركيزي الحالي هو على تمكين تسليم ادارة العلاقات مع تحجيم وتوفير القيادة المعمارية في بيئات رشيقة. أعمل حاليا من أجل ادارة العلاقات مع مزود الرابع يقودهم إلى السماء المؤسسة، خدمة واحدة في وقت واحد.
يمكنك متابعة لي على تويتر أو تحقق لي على لينكيدين.
خدمات الكيان: عندما تكون الخدمات الميكروية أسوأ من المتجانسات.
ويبدو أن الخدمات القائمة على الكيان تبدو مدعومة من قبل بعض المصادر الموثوقة جدا. وهذا أمر مؤسف لأنه شيء من نمط مضاد يمكن أن تقوض العديد من فوائد تحلل متراصة إلى ميكروسرفيسز.
ننسى تغطية التعليمات البرمجية - تصميم الاختبار يجب أن يكون مدفوعا السلوكيات.
إحصاءات تغطية الاختبار هي محبوبة كثيرا من قبل فرق الإدارة وأدوات جودة التعليمات البرمجية. أنها تميل إلى ربط مستوى عال من التغطية مع قواعد رمز قوية، وإدارة جيدة. خطأ، كما اتضح.
الأحداث، ساجاس وسير العمل: إدارة العمليات طويلة المدى بين الخدمات.
يمكن للهيكل القائم على الحدث أن يؤدي إلى سلاسل معقدة من الأحداث التي يصعب إدارتها. ويمكن تخفيف هذه المشاكل من خلال التصميم الدقيق بدلا من اللجوء إلى قواعد بيانات الدولة المشتركة أو محركات سير العمل.
الدين التقني هو الاستعارة المفرطة والكسول.
قد يكون الدين التقني استعارة مفيدة لوصف كيفية تصميم سيئة للسوء يقوض الإنتاجية للجمهور غير الفني، ولكنه لا يساعد في فهم المشاكل على المدى الطويل التي تؤثر على قواعد التعليمات البرمجية.
كيف يمكن أن يساعد تصميم دريفن ديسين في تطوير رشيق واسع النطاق؟
فرق رشيقة قضاء برامج النمذجة الوقت سواء كانوا على استعداد لقبول ذلك أم لا. إن اعتماد تقنية مثل تصميم دريفن دريفن يمكن أن يساعد على جعل هذا أكثر كفاءة، وخاصة على نطاق واسع.
تشغيل تطبيق وحدة التحكم الأساسية كخدمة ويندوز.
على الرغم من أن كور لا تدعم مباشرة إنشاء ويندوز سيرفيسز هناك العديد من الطرق المختلفة لإنشاء التطبيقات التي يمكن تسجيلها وتشغيلها كخدمات.
متى تصبح إعادة بيعها إعادة كتابة؟
إعادة هيكلة يصف تقنية محددة جدا ومتحكم بها لتحسين التعليمات البرمجية. المشكلة هي أنه غالبا ما يستخدم لوصف تغييرات الجملة لقواعد التعليمات البرمجية التي ينبغي أن تعامل على أنها إعادة كتابة.
كتابة وحدات اختبار وظائف أزور باستخدام C #
يمكنك الآن كتابة وظائف أزور المترجمة في C # مع تغطية اختبار وحدة كاملة، على الرغم من أن هناك بعض العقبات على طول الطريق.
إصدار خدمات ريستفول.
I’ve talked about this in various venues and also cover it in my Pluralsight REST Fundamentals course, but the topic of how to version RESTful services has been popping up a bunch recently on some of the ASP Web API discussion lists, and my friend Daniel Roth asked if I could serialize some of that presentation content into a blog post – so here goes.
First, note that while the focus here is on RESTful services and not just HTTP services, the same principles can potentially apply to HTTP services that are not fully RESTful (for example, HTTP services that do not use hypermedia as a state transition mechanism).
When talking about versioning, the most important question to ask is “what are you wanting to version?” The logical extension to this question is, “what is the contract between your service and client?” This is naturally important since the contract is the thing you want to version.
In the “old world” of Web services, the contract was the service. Service actions (and associated semantics) along with data formats and other metadata were covered by the definition of the service, which was exposed as a single URL (the service, that is – I’m grouping together all RMM L0 services here). As such, when it came to the question of how to version the service, the answer was generally pretty simple: if the contract is the service, and the service is exposed as a URL, then the solution is to version the URL. As such, you’ll see a lot of this if you browse around –
(Not trying to pick on NuGet here – it just happens to be a service API that I’m pretty familiar with at the moment)
It doesn’t take much imagination to see how unwieldy this can get after even a few iterations – especially when you’re clients are interacting with the service by generating strongly typed proxies and then pretending that there is no network (yes, I am picking on WCF here).
So how is this different for RESTful services?
Well, we should start by again asking the question, “What is the contract for a RESTful service?” The answer is, IMHO, the uniform interface. The uniform interface is made up of 4 constraints –
Identification of resources Manipulation through representations Self-descriptive messages Hypermedia as the engine of application state (HATEOAS)
While all of these constraints are important to understand and take into consideration for the overall design of a RESTful system, I’m going to highlight the first 2 with respect to versioning.
First, let’s look at resources. A resource is any named information or concept – this is nice from a philosophical perspective, but maybe a little less helpful in how it enables us to think about versioning, so let’s look at it another way (as Fielding describes). A resource is a 0..n mapping between an identifier and a set of entities that changes over time. Here’s a concrete example:
I have 3 daughters: Grace, Sarah, and Abigail. However, this was not always the case – in fact, during the time period before Grace was born, the resource map of my family looked like the following:
As you can see, I had defined (in my mind) a bunch of named concepts – and at that point in time, they didn’t map to any actual entities (e. g. kids). Now, when Grace was born, the resource map looked like the following:
As you can see here, all of my named concepts map to a single entity – Grace. But what about when Sarah came along? Then the map changed to the following:
As you can now see, my “children” collection resource maps to multiple entities, and “youngest child” now maps to Sarah rather than Grace.
The point here is that the resource *concept* has not changed here – and more importantly, though the specific entity mappings have changed over time, the service has done this in a way that preserves the meaning of identified domain abstraction (e. g. children).
A representation, on the other hand, is an opaque string of bytes that is effectively a manifestation of a resource. Representations can come in many different formats and the process of selecting the best format for a given client-server interaction is called content negotiation. The self-descriptive message constraint of the uniform interface adds that the information needed to process a representation, regardless of format, is passed in the message itself.
I wanted to give this brief explanation of resources and representations because it’s important to have a clear understanding of what they are so that you can know when to version them. So let’s get back to versioning…
So, if the contract for a RESTful service is the uniform interface, then the answer to the question of how to version the service is “it depends on which constraint of the uniform interface you’re changing.” In my experience, there are 3 common ways that you can version (I’m sure there are more, but these are the 3 that I’ve come across most regularly).
Versioning Strategy 1: Adding content to a representation.
In the case where you’re adding something to a representation – let’s say that you’re adding a new data field “SpendingLimit” to a customer state block as follows:
“Name”: “Some Customer”,
In this case, the answer to the versioning question is to just add it. Now, this assumes that your clients will ignore what they don’t understand. If you’ve written clients in such a way that you can’t make that assumption, then you should fix your clients J – or perhaps you need to look at the next strategy…
Versioning Strategy 2: Breaking changes in a representation.
In the case where you’re either removing or renaming content from an existing representation design, you will be breaking clients. This is because even if they are built to ignore what they don’t understand, by making this sort of change on the server, you’re changing what they already understand. In this case, you want to look at versioning your representation . HTTP provides a great facility for doing this using content negotiation. For example, consider the following:
GET localhost:8800/bugs HTTP/1.1.
This request gives me the following response fragment – as you can see, I’m working from an HTML base media type:
Now what if, for some reason, I needed to change the link relationship values? Remember that based on the hypermedia constraint of the uniform interface, my client needs to understand (e. g. have logic written against) those link relationship values, so renaming them would break existing clients. However, in this case, I’m not really changing the meaning of the resources or the entities that the resources map to. Therefore, I can version my representation and enable clients that know how to work with the newer version to request the newer version using the HTTP accept header as follows:
Therefore, this request:
GET localhost:8800/bugs HTTP/1.1.
Will now give me the new response format:
One other thing that I want to mention here – you’ve probably noticed that I’m using the language of representation design and representation versioning as opposed to content type design/versioning. This is deliberate in that many (most?) times, you’re going to design your representations completely on top of existing content types (e. g. xml/json/html/hal/etc). Without wading into the custom media type debate in this post, my point is that when I’m talking about versioning the representation here, I’m talking about versioning the domain-specific aspects of your representation that your client needs to be aware of.
Versioning a representation over an existing media type will look slightly differently from what’s shown above in that you’ll pass a standard media type identifier in the HTTP accept header along with an additional metadata element to identify your representation-specific aspects and then do content negotiation based on the combined description. There are several different ways to add the representation-specific metadata, including media type parameters and custom HTTP headers.
Versioning Strategy 3: Breaking the semantic map.
In both of the prior strategies, all changes, breaking and non-breaking, have been related to the representations. This is a really good thing as it enables the resources (and more importantly, the URL resource identifiers) to remain stable over time. However, there may be occasions – hopefully rarely – when you need to break the meaning of a resource and therefore the mapping between the resource and its set of entities. As an example, as I get older and my kids grow up and leave, let’s say that I start returning my pets as children. In this case, I’ve changed the meaning of the “children” resource and thereby broken that aspect of the contract between my client and service. The solution then, in this case, is to version the resource identifier itself.
If I did a lot of this sort of resource versioning, it is very possible that I could end up with an ugly-looking URL space. But REST was never about pretty URLs and the whole point of the hypermedia constraint is that clients should not need to know how to construct those URLs in the first place – so it really doesn’t matter whether they’re pretty or ugly – to your client, they’re just strings.
So to summarize.
This post ended up being longer than I had planned, so here’s the summary.
In REST, the contract between clients and services is the uniform interface How you version depends on what part of the uniform interface you’re changing If you’re adding only, go ahead and just add it to the representation. Your clients should ignore what they don’t understand If you’re making a breaking change to the representation, version the representation and use content negotiation to serve the right representation version to clients If you’re changing the meaning of the resource by changing the types of entities it maps to, version the resource identifier (e. g. URL)
About Howard Dierking.
I also think that version in the URL is a part of base URL from client’s point of view, so basically changing version does not change semantics for the resources, but only response (representation). When you request GET /api/v1/books or GET /api/v2/books it’s like requesting GET /api/books with client designed for using with v1 and v2 respectively. You don’t hardcode version in client, you configure it from the outside and use relative resources (for example /books ) so the only problem here would be misconfiguration (e. g. using v1 client with v2 resources).
Sorry for resurrecting such old thread, but I must ask: did you write down that new post ;-)?
In my opinion in your second approach you are confusing representation with entity structure. Representation is about the format in which you send the information or your client expects to receive it (xml, html, json, etc), in this case the resource that you are pointing to. Which means if I request the same resource but with different representation (xml, json, etc) at the same instant of time then my resources should point to the same exact entity structure and contents but with a different format, the thing that changes is the way it is dressed.
If you add a new field to the entity your resource is mapping to (like in the first approach you describe: adding SpendingLimit to customer entity), what you are really doing is creating a new version of your entity with its own set of properties (in this case with all the properties from the previous plus a new one), then you need to create a new resource (or redefine the mappings) to map to that entity as you do in your children example when having a new child.
This is similar to what Roy Fielding describes in his blog when talking about bulk operations: …If you find yourself in need of a batch operation, then most likely you just haven’t defined enough resources… (roy. gbiv/untangled/2008/rest-apis-must-be-hypertext-driven#comment-743). In the sense that changes to the information structure (in this case number of entities mapped by the resource) is about identifying those entities by mapping them to a proper resource.
Based in all that, in my opinion and experience versioning a REST API in terms of changing entity structure should be done in the URI, but at the level of resource id rather than at the level of API, which means later and not earlier in the URL.
Doing it this way allows the client to request specifically the resource they want which maps to the entity they need. Without having to mess with headers and custom media types which is really problematic when implementing in a production environment.
‘especially when you’re clients’ should probably read ‘especially when your clients’
Must take issue with the “before Grace was born, the resource map of my family looked like the following” showing a Grace node (not subscribing to “a boy named Sue” or “the grace of God” unconditionally), e. g. AFTER birth of Sarah the Sarah node appears.
haha, no worries. I like beer a great deal, but I live in WI. So…. there’s that.
clearly, I’ve done a terrible job here. I will publish it today (will go isolate myself in a coffee shop) and also owe you a beer or 2…
Ok, last attempt. Wondering if you ever posted something somewhere that I missed? شكر!
I think I am finally catching an understanding of using the accept value to version the representations. And I can certainly see the value of being able to version 1 specific method vs having to accept all changes that might belong to a new service version. That said — I would really like to hear/read what you have found out in relation to NuGet API. I just took a look and didn’t see another post that seemed to cover it — hate to pester, but is it still coming?
Just got back from vacation last night – so between that and the forthcoming holiday, should have something in a week or so…
Hi Howard, just wondering where you’re at with your post describing your thoughts on all of this?
Thanks for writing back! Fantastic, I look forward to reading it.
Aaron, these are some really great comments. As it turns out, I’ve been thinking a lot about this recently and have been having some conversations around the general weaknesses of purely server-driven content negotiation (for many of the reasons you mentioned). Rather than noting my thoughts in comments, I’m going to just do a new post describing where my thinking is at the moment regarding conneg and what that means for versioning/metadata/linking. Much of this thinking has been coming out of the NuGet API redesign effort, so should be able to provide some concrete examples behind the concepts.
Howard, this was a fantastic read and a nice compliment to your pluralsight video as well. Where things break down for me (and others that I know) is when we make the assumption that our consumers will be able to specify content types or version numbers in a request for a resource. Maybe you can chime in here. Drawing from your example, let’s say that your uri is as follows:
Performing a GET, with accept: text/json against the above api returns a data representation of Grace. So you might get back.
Performing a GET, with accept: image/jpg against the above api, will return an image of Grace.
So me as a consumer, might write a web page to consume that api. Assuming that I want the image representation of Grace, I would write the following HTML:
Where this breaks down is that I cannot specify the accept type in the image tag, so how can I be sure that the server will default my request to image/jpg?
Further, If i wanted version 2, I cannot specify that either. So I feel like there might actually be some validity in using a version based uri scheme for these types of scenarios.
Many times, consumers of your apis will just be the average browser user, who doesn’t have the first clue about HTML, so the only way for these users to access version 2 of grace’s image would be via api/v2/children/grace/image. Certainly they’re not going to figure out a way to specify a version type or accept type in the header.
So unless I’m missing something, it just feels like we have to consider our audience when designing our restful services.
I would REALLY love your thoughts on this. I think where RESTFul design practices break down for people is around the disparity in which they are consumed.
“but it seems an illogical default” & # 8211؛ it’s not an illogical default… it would be more illogical to return version 2.1 definitions.
Just got pointed to this from Mike Wasson’s blog post. A couple of queries on implementing this.
You’d presumably want to accept some standard mime type as well? Isn’t this slightly manipulating content negotiation more than the intended usage – your response isn’t going to be a different content type as such. If going this route, wouldn’t your preferred accept type be Content-Type: text/html;apiVersion=1.1?
In your closing you stipulate (I’m paraphrasing) that if you’re changing the meaning of the resource, change the URL. In most mature production systems this would mean having both versioning strategies in play – content type negotiation and URLs. Isn’t REST, and the API strategy in general, supposed to promote inferable APIs which is a little tricky if I have to reference /api/v2/person and supply a specific content type? i. e. I’d have to provide both the v2 in the URL and a v2 in the content type otherwise the next ‘breaking change to the representation’ (bullet point 2 in closing) that is made by the api would also break my client code as the logical default content-type, if using text/html, would be the ‘latest’ version of the api? Obviously this could be fixed by not deafulting to the latest version of the api but it seems an illogical default; my point is that mixing the two seems somewhat fraught.
شكرا لكم! I believe I have a lot to learn, but you provided a bunch of useful information.
so there are a few questions in here, some related to versioning, some related to HTTP, and some related to REST in general. I’ll try to address a couple points here, but very strong urge you to read the Fielding dissertation for a more comprehensive treatment of REST, as well as other architectural styles that REST compares/contrasts with.
“When you are using the accept header for versioning, aren’t you essentially extending the URI to include the header?”
ليس صحيحا. At the meta level, in this example the accept header (though content negotiation can be based on any bit of metadata, not just the accept header) is used to make a statement about the version of the *representation* whereas the URL identifies a resource. Practically, this means that that set of URLs that make up a service’s resource model can remain stable across multiple versions of changes in the representation (including the addition of new capabilities).
One thing that used to keep me from fully getting the concept of versioning representations like this was when I used to equate representation with entity (e. g. I have a bug representation, a customer representation, etc..). When I redefined representation (and the representation design) to include everything that could show up in the representation (Mike Amundsen calls these ‘state blocks’ in his book shop. oreilly/product/0636920020530.do), versioning the representation made a lot more sense wrt both the value in doing it and a practical approach.
“you are now requiring the REST server to now read the HTTP headers, instead of just the request”
At the risk of sounding like I’m nitpicking, there is no such thing as a REST server – REST is just a style of distributed systems architecture. I am using an HTTP server, though, and am quite confident that it knows how to read and process HTTP headers.
“it should be implemented over a protocol that can transfer a meaningful representational state, such as HTTP”
Based on my reading waaayyy too much into this statement, I think you’re conflating a couple different things together (specifically, the self-describing message constraint of REST with the definition of representation state with the definition of HTTP) – the dissertation should help here better than my comments on your comments.
‘Technically, this could be achieved in the HTTP request: ” HTTP/1.1″‘
I don’t see how you could realize the self-describing message constraint (or the stateless constraint or the caching constraint, etc.) of REST with a protocol version, resource identifier, and one piece of control flow data. The data elements in the RESTful style include resource metadata, representation metadata, and control data – which HTTP implements as headers. As I remember it, Fielding’s only issue with this design was that all of the different types of metadata were reduced to the same flat list of headers in HTTP, making it less apparent what header was what type of metadata. One comment he did make that validates something you mentioned was that he agreed that cookies were generally contrary to the principles of the RESTful style, as they reduced the visibility (e. g. self-describing messages) and in practice, tend to be used in ways that also undermine the stateless constraint.
Past that, I’m not sure that we’ve gotten carried away with using a major component of a protocol that was meant to be used as an application protocol.
Hope this long-winded response was helpful – thanks for commenting!
When you are using the accept header for versioning, aren’t you essentially extending the URI to include the header? I don’t see much of a difference between GET /bugs/v2 and GET /bugs with a header with v2, except you are now requiring the REST server to now read the HTTP headers, instead of just the request.
At the University of Minnesota, we have recently been discussing REST architecture in the Software Engineering program. I haven’t read Roy Fielding’s dissertation on REST yet, but I think I should. In my understanding of REST, it should be implemented over a protocol that can transfer a meaningful representational state, such as HTTP. Technically, this could be achieved in the HTTP request: ” HTTP/1.1″. But I think we took it too far by using HTTP headers (authentication, cookies, and in your example accept).
What do you think about this?
2 separate issues (‘things’ getting unwieldy and pretending that there is no network) – sorry if the way the post was worded made it seem like I was conflating the two.
Anyways, here’s the scenario I was thinking of wrt the ‘unwieldy’ تعليق. Because the unit of versioning is the service in the Web services world, then most of the changes that you make to to the service (e. g. a service operation) will require you to increment the service version. Coupled with the fact that services tend to be more coarsely grained means that you can very quickly end up with myhost/api/v2*10^8 (ok, that may be a *little* dramatic). Having this many versions is confusing to clients, but more importantly can become a pain to maintain on the server (e. g. how many interfaces does your service class end up implementing over time?).
There are plenty of problems with frameworks that enable you to pretend that there is no network (e. g. work with services as if they were local objects via proxies) – but in this post, I was thinking of the difficulty that can happen when the service versions change and clients need to rev to support the new service version – even if the client in question only needs the functionality of 1 operation/resource. In this case, even though the client is only using one new capability (or 1 bug fix), the client needs to test for everything that has changed in the new version.
Howard, I’m a bit confused about “It doesn’t take much imagination to see how unwieldy this can get after even a few iterations – especially when you’re clients are interacting with the service by generating strongly typed proxies and then pretending that there is no network”
Comments
Post a Comment