2013-08-26 4 views
6

कतार में लंबे समय के परिचय के आधार पर स्वीकार करें ...वेब एपीआई कार्रवाई चयन हैडर

मैं एक संसाधन

http://my-awesome-product.com/api/widgets/3 

जो 3. के id के साथ एक विजेट वेब एपीआई मैं परिभाषित करेगा में प्रतिनिधित्व पर परिभाषित किया है एक नियंत्रक कि संसाधन सेवा करने के लिए इस प्रकार है:

public class WidgetsController : ApiController 
{ 
    public Widget Get(int id) 
    { 
     return new Widget(...); 
    } 
} 

अब, Widget वर्ग संभवतः काफी बड़ा हो सकता है, और से बैंडविड्थ को बचाने के लिए चाहते हैं वेब सर्वर के लिए डेटाबेस, और वेब सर्वर से क्लाइंट तक, मैं कई डीटीओ कक्षाएं बनाता हूं जिनमें कुल Widget के फ़ील्ड की प्रतिबंधित संख्या होती है। उदाहरण के लिए:

public class WidgetSummary 
{ 
    public int Id { get; set; } 
    public string Code { get; set; } 
    public string Description { get; set; } 
    public decimal Price { get; set; } 
} 

public class FullWidgetForEditing 
{ 
    public int Id { get; set; } 
    public string Code { get; set; } 
    public string Description { get; set; } 
    public decimal Weight { get; set; } 
    public decimal Price { get; set; } 
    public Color Color { get; set; } 
    public decimal Width { get; set; } 
    public decimal Height { get; set; } 
    public decimal Depth { get; set; } 
} 

public class WidgetForDropDownList 
{ 
    public int Id { get; set; } 
    public string Code { get; set; } 
} 

इन Widget अभ्यावेदन के साथ, ग्राहक WidgetSummary प्रदर्शन के लिए सभी Widget रों का एक सारांश ग्रिड पर व्यवस्था में अनुरोध करेंगे, यह एक विशिष्ट Widget के संपादन पृष्ठ पर FullWidgetForEditing अनुरोध करेंगे, और ऑर्डर फॉर्म पर ड्रॉप डाउन सूची में उपयोग के लिए WidgetForDropDownList का अनुरोध करेगा।

मैं क्या बाकी के बारे में समझते हैं, तक पहुँचने के लिए से

एक Widget कोई एक URL होना चाहिए के रूप में यह एक भी संसाधन है, उसकी प्रस्तुति की परवाह किए बिना और ग्राहक में Widget को पुनः प्राप्त करने के लिए एक मीडिया प्रकार पैरामीटर के साथ Accept हेडर निर्दिष्ट करना चाहिए इसके विभिन्न रूपों, उदाहरण के लिए my-awesome-product.type=widgetsummary, my-awesome-product.type=fullwidgetforediting, और my-awesome-product.type=widgetfordropdownlist

मैं वेब एपीआई में है कि प्राप्त कर सकते थे इसलिए जैसे अनुरोध के शीर्ष लेख निरीक्षण:

public class WidgetsController : ApiController 
{ 
    public object Get(int id) 
    { 
     if (Request.Headers.Accept.Any(x => x.Parameters.Any(y => y.Name == "my-awesome-product.type" && y.Value == "widgetsummary"))) 
     { 
      return new WidgetSummary(...); 
     } 
     else if (Request.Headers.Accept.Any(x => x.Parameters.Any(y => y.Name == "my-awesome-product.type" && y.Value == "fullwidgetforediting"))) 
     { 
      return new FullWidgetForEditing(...); 
     } 
     else if (Request.Headers.Accept.Any(x => x.Parameters.Any(y => y.Name == "my-awesome-product.type" && y.Value == "widgetfordropdownlist"))) 
     { 
      return new WidgetForDropDownList(...); 
     } 

     throw new HttpResponseException(HttpStatusCode.NotAcceptable); 
    } 
} 

बहरहाल, यह गंदा हो जाता है प्रकार की संख्या बढ़ने जल्दी के रूप में और इकाई परीक्षण और अधिक कठिन बना देता है। क्या मैं सच में करना चाहते हैं निम्नलिखित है:

public class WidgetsController : ApiController 
{ 
    [HttpGet(MediaType = "my-awesome-product.type", MediaTypeValue = "widgetsummary")] 
    public WidgetSummary GetWidgetSummary(int id) 
    { 
     return new WidgetSummary(); 
    } 

    [HttpGet(MediaType = "my-awesome-product.type", MediaTypeValue = "fullwidgetforediting")] 
    public FullWidgetForEditing GetFullWidgetForEditing(int id) 
    { 
     return new FullWidgetForEditing(); 
    } 

    [HttpGet(MediaType = "my-awesome-product.type", MediaTypeValue = "widgetfordropdownlist")] 
    public WidgetForDropDownList GetWidgetForDropDownList(int id) 
    { 
     return new WidgetForDropDownList(); 
    } 
} 

और मीडिया प्रकार के आधार पर विशिष्ट कार्रवाई विधि के लिए जाल एपीआई मार्ग की है। मैंने ApiControllerActionSelector को ओवरराइड करने की जांच की, हालांकि, मैंने इस विशेषता के लिए मौजूदा कोड की बड़ी मात्रा में खींचना शुरू कर दिया क्योंकि मुझे वास्तव में डिफ़ॉल्ट क्रिया चयन चाहिए, लेकिन संदिग्ध कार्यों के मामले में, मैं मीडिया के आधार पर कार्यों की सूची फ़िल्टर करना चाहता हूं प्रकार। मैं वास्तव में यह गैर-घुसपैठ करना चाहता हूं ताकि मैं सम्मेलन रूटिंग, मानक विशेषता रूटिंग (जो वेब एपीआई v2 में है) और यदि आवश्यक हो तो उसी नियंत्रक में यह अनुमानित विशेषता रूटिंग मिश्रण कर सकते हैं।

प्रश्न समय: क्या वर्तमान में वेब एपीआई के साथ ऐसी रूटिंग रणनीति को लागू करना संभव है? क्या मुझे यह प्राप्त करने के लिए ApiControllerActionSelector को पूरी तरह से पुन: कार्यान्वित करना होगा (और फिर सुनिश्चित करें कि मेरा पुनर्मूल्यांकन अद्यतित रहता है)?

+0

flipchart, मैं भी आप वास्तव में क्या वर्णित रहा हूँ - एक यूआरएल का 1 वस्तु (नहीं इसके प्रारूप, या वापसी प्रकार) का प्रतिनिधित्व करना चाहिए। क्या आपको कभी समाधान मिला? मैं उलझन में हूं कि क्यों डिफ़ॉल्ट चयनकर्ता ओवरराइड कर रहा था इतना कोड ले रहा था, क्या आप सिर्फ अपने स्वीकृत हेडर को संभाल नहीं सकते हैं और यदि आपको कोई मैच नहीं मिलता है, तो अनुरोध को बेस क्लास में पास कर दें? मैं क्या खो रहा हूँ? – jeremyh

उत्तर

2

तो सवाल यह है कि आपको विचार करने की आवश्यकता है। क्या वे वास्तव में तीन प्रतिनिधित्व हैं, या तीन अलग-अलग संसाधन हैं? यदि आपने उन प्रस्तुतियों को कैश करने का निर्णय लिया है, तो क्या यूआरआई कैश किए गए प्रतिनिधित्व की पहचान करने के लिए पर्याप्त होगा, या आपको स्वीकृति हेडर पर भी बदलाव करने की आवश्यकता होगी?

यदि आप स्वीकार करते हैं कि वे संसाधन होने के लिए पर्याप्त हैं तो उन्हें विभिन्न यूआरएल द्वारा पहचाना जाना चाहिए। यदि आप अपने प्रतिक्रियाओं में हाइपरलिंक्स का उपयोग करने का निर्णय लेते हैं, तो क्या आप 'widgeteditform' से स्वतंत्र रूप से 'widgetsummary' को इंगित करने की क्षमता नहीं चाहते हैं?

आमतौर पर जब आप एक निश्चित मीडिया प्रकार का समर्थन करने में सक्षम होते हैं तो विभिन्न क्लाइंट डिवाइसों का समर्थन करना चाहते हैं तो एकाधिक प्रतिनिधित्व की आवश्यकता होती है। जैसे डिवाइस ए को रिप 1 मिल जाता है और डिवाइस बी को रिप 2 मिलता है। यह दुर्लभ है कि आप डिवाइस ए को डिवाइस ए और रिप 1 और रिप 2 दोनों तक पहुंचाना चाहते हैं।

बस मेरे विचार ...

+0

प्रश्न पर ही, हाँ, आप सही हैं। सामान्य फ्लिपचार्ट में एक दिलचस्प विषय है, फिर भी एपीआई वर्जनिंग और मीडियाटाइप या एक्स-मीडिया टाइप्स के साथ रूटिंग ... – Mauro