2011-10-14 16 views
7

मैं एक आरईएसटी एपीआई बना रहा हूं और मैं ग्राहकों से अनुरोधों को बंडल करने की अनुमति के साथ खेल रहा हूं। बंडल करके मेरा मतलब है कि वे एक अनुरोध भेज सकते हैं, जिसमें कई "असली" अनुरोध हैं, और वे क्लाइंट को एक साथ पहुंचाते हैं। आम तौर पर जावास्क्रिप्ट AJAX अनुरोध। कुछ इस तरह:बंडलिंग एपीआई अनुरोध

POST /bundlerequest 

["/person/3243", "/person/3243/friends", "/comments/3243?pagesize=10&page=1", "/products", "/product/categories" ] 

(बंडल अनुरोध केवल, अनुरोध प्राप्त हो सकता है अब तक कम से कम) के इस बंडलिंग कि है इस तरह इस

{ 
    "success" : ["/person/3243", "/person/3243/friends", "/comments/3243?pagesize=10&page=1", "/products", "/product/categories" ], 
    "error" : [], 
    "completiontime" : 94, 
    other relevant metadata... 
    "responses" : [ 
     {"key" : "/person/3243" , "data" : {"name" : "John", ...} }, 
     {"key" : "/person/3243/friends" , "data" : [{"name": "Peter", "commonfriends" : 5, ...}] }, 
     etc... 
    ] 
} 

लाभ कुछ वापसी करने का इरादा है यह अनुरोधों की संख्या को कम करता है और उदाहरण के लिए मोबाइल उपकरणों पर विशेष रूप से महत्वपूर्ण है।

तो मेरा पहला सवाल यह है कि, यह मेरे लिए एक अच्छा तरीका है? क्या किसी को ऐसा कुछ करने का अनुभव है?

AFAIK इसे हल करने का सामान्य तरीका संयुक्त डेटा को वापस करने के लिए सर्वर साइड कोड लिखना है, जो मुझे विश्वास है कि ग्राहक के लिए प्रासंगिक है। (उदाहरण के लिए ट्विटर उपयोगकर्ता स्ट्रीम यह करता है, व्यक्ति की जानकारी, नवीनतम ट्वीट्स, नवीनतम व्यक्तिगत संदेश इत्यादि को जोड़ती है) लेकिन यह एपीआई को बहुत ही राय देता है और जब ग्राहक को परिवर्तन की आवश्यकता होती है तो सर्वर को अनुकूलित करने के लिए समायोजित करने की आवश्यकता हो सकती है।

और दूसरा सवाल यह है कि इसे कैसे कार्यान्वित किया जाए?

मेरा बैकएंड एएसपी.नेट एमवीसी 3 और आईआईएस 7 है। क्या मुझे इसे आवेदन में लागू करना चाहिए, जिसमें एक बंडलरक्वेट कार्रवाई है जो आंतरिक रूप से अनुरोध में निर्दिष्ट अन्य कार्रवाइयों को कॉल करता है?

इसे आईआईएस 7 में सीधे लागू किया जा सकता है? एक मॉड्यूल लिखना जो पारदर्शी रूप से/bundlerequest के अनुरोधों को रोकता है और फिर सभी संबंधित उप अनुरोधों को कॉल करता है, जिससे आवेदन पूरी तरह से बंडल से अनजान हो जाता है? इससे मुझे एप्लिकेशन-अज्ञेय तरीके से इसे लागू करने की भी अनुमति मिल जाएगी।

+0

यह एक अच्छा विचार की तरह लगता है। –

+0

क्या वे सभी यूआरएल केवल JSON लौटने जा रहे हैं? या कुछ एचटीएमएल आंशिक और अन्य सामान वापस कर सकते हैं? –

+0

@DarinDimitrov हाँ JSON केवल, हालांकि मुझे उपयोगकर्ता के लॉग इन होने या उदाहरण के लिए एपीआई के हिस्सों तक पहुंच नहीं होने के साथ संभावित समस्याएं दिखाई देती हैं, और फिर लॉगिन पृष्ठ पर रीडायरेक्ट हो सकती हैं। ये समस्याएं हैं जिन्हें मुझे हल करना होगा। –

उत्तर

3

आप एक asynchronous controller इस्तेमाल कर सकते हैं सर्वर पर उन अनुरोधों तरह इकट्ठा करना।

public class BundleRequest 
{ 
    public string[] Urls { get; set; } 
} 

public class BundleResponse 
{ 
    public IList<string> Success { get; set; } 
    public IList<string> Error { get; set; } 
    public IList<Response> Responses { get; set; } 
} 

public class Response 
{ 
    public string Key { get; set; } 
    public object Data { get; set; } 
} 

तो नियंत्रक:

public class BundleController : AsyncController 
{ 
    public void IndexAsync(BundleRequest request) 
    { 
     AsyncManager.OutstandingOperations.Increment(); 
     var tasks = request.Urls.Select(url => 
     { 
      var r = WebRequest.Create(url); 
      return Task.Factory.FromAsync<WebResponse>(r.BeginGetResponse, r.EndGetResponse, url); 
     }).ToArray(); 

     Task.Factory.ContinueWhenAll(tasks, completedTasks => 
     { 
      var bundleResponse = new BundleResponse 
      { 
       Success = new List<string>(), 
       Error = new List<string>(), 
       Responses = new List<Response>() 
      }; 
      foreach (var task in completedTasks) 
      { 
       var url = task.AsyncState as string; 
       if (task.Exception == null) 
       { 
        using (var response = task.Result) 
        using (var stream = response.GetResponseStream()) 
        using (var reader = new StreamReader(stream)) 
        { 
         bundleResponse.Success.Add(url); 
         bundleResponse.Responses.Add(new Response 
         { 
          Key = url, 
          Data = new JavaScriptSerializer().DeserializeObject(reader.ReadToEnd()) 
         }); 
        } 
       } 
       else 
       { 
        bundleResponse.Error.Add(url); 
       } 
      } 
      AsyncManager.Parameters["response"] = bundleResponse; 
      AsyncManager.OutstandingOperations.Decrement(); 
     }); 
    } 

    public ActionResult IndexCompleted(BundleResponse response) 
    { 
     return Json(response, JsonRequestBehavior.AllowGet); 
    } 
} 

और अब हम यह आह्वान कर सकते हैं:

var urls = [ 
    '@Url.Action("index", "person", new { id = 3243 }, Request.Url.Scheme, Request.Url.Host)', 
    '@Url.Action("friends", "person", new { id = 3243 }, Request.Url.Scheme, Request.Url.Host)', 
    '@Url.Action("index", "comments", new { id = 3243, pagesize = 10, page = 1 }, Request.Url.Scheme, Request.Url.Host)', 
    '@Url.Action("index", "products", null, Request.Url.Scheme, Request.Url.Host)', 
    '@Url.Action("categories", "product", null, Request.Url.Scheme, Request.Url.Host)' 
]; 
$.ajax({ 
    url: '@Url.Action("Index", "Bundle")', 
    type: 'POST', 
    contentType: 'application/json; charset=utf-8', 
    data: JSON.stringify(urls), 
    success: function(bundleResponse) { 
     // TODO: do something with the response 
    } 
}); 
बेशक

कि नियंत्रक द्वारा लौटा दी जाएगी एक दृश्य के मॉडल को परिभाषित करते हुए चलो पहले शुरू आपकी विशिष्ट जरूरतों को अनुकूलित करने के लिए कुछ ट्वीकिंग आवश्यक हो सकती है। उदाहरण के लिए आपने सत्र समाप्त होने के साथ AJAX अनुरोध भेजने का उल्लेख किया है जो लॉगऑन पेज पर रीडायरेक्ट कर सकता है और इस प्रकार त्रुटि को कैप्चर नहीं कर सकता है। यह वास्तव में एएसपी.नेट में एक पिटा है। फिल हैक blogged एक अशिष्ट तरीके से इस अवांछित व्यवहार को रोकने के लिए एक संभावित तरीका है। आपको अनुरोधों में कस्टम हेडर जोड़ने की जरूरत है।

+0

एक बहुत विस्तृत उत्तर के लिए धन्यवाद और फॉर्म प्रमाणीकरण समस्या को हल करने के लिए मुझे सही दिशा में इंगित करता है। मुझे जो चाहिए वह ठीक लगता है। मैं इस पर अपने कार्यान्वयन का आधार रखूंगा और देख सकता हूं कि यह मेरे आवेदन में कैसे फिट बैठता है। –

संबंधित मुद्दे