2009-11-12 12 views
15

मैं एक जावास्क्रिप्ट लाइब्रेरी विकसित कर रहा हूं जिसका उपयोग तीसरे पक्ष के डेवलपर्स द्वारा किया जाएगा।क्या हमें जावास्क्रिप्ट एपीआई में विधि तर्क मान्य करना चाहिए?

समारोह DoSomething (ARG1, ARG2, विकल्प)

  • ARG1, ARG2 हैं 'आवश्यक' सरल प्रकार तर्क: एपीआई इस हस्ताक्षर के साथ तरीके शामिल हैं।
  • विकल्प वैकल्पिक हैश युक्त एक हैश ऑब्जेक्ट है।

क्या आप इसे सत्यापित करने की अनुशंसा करेंगे: - तर्क प्रकार मान्य हैं? - विकल्प विशेषताएँ सही हैं? उदाहरण के लिए: डेवलपर को सफलता के बजाय Succes पर गलती से गुजरना नहीं था?

  • प्रोटोटाइप.जेएस जैसी लोकप्रिय लाइब्रेरी क्यों मान्य नहीं हैं?

उत्तर

4

विस्तृत उत्तरों के लिए धन्यवाद।

नीचे मेरा समाधान है - सत्यापन के लिए एक उपयोगिता वस्तु जिसे आसानी से कुछ भी सत्यापित करने के लिए आसानी से बढ़ाया जा सकता है ... कोड अभी भी काफी छोटा है ताकि मुझे उत्पादन में इसे पार्स करने की आवश्यकता न हो।

WL.Validators = { 

/* 
* Validates each argument in the array with the matching validator. 
* @Param array - a JavaScript array. 
* @Param validators - an array of validators - a validator can be a function or 
*      a simple JavaScript type (string). 
*/ 
validateArray : function (array, validators){ 
    if (! WL.Utils.isDevelopmentMode()){ 
     return; 
    } 
    for (var i = 0; i < array.length; ++i){    
     WL.Validators.validateArgument(array[i], validators[i]); 
    } 
}, 

/* 
* Validates a single argument. 
* @Param arg - an argument of any type. 
* @Param validator - a function or a simple JavaScript type (string). 
*/ 
validateArgument : function (arg, validator){ 
    switch (typeof validator){ 
     // Case validation function. 
     case 'function': 
      validator.call(this, arg); 
      break;    
     // Case direct type. 
     case 'string': 
      if (typeof arg !== validator){ 
       throw new Error("Invalid argument '" + Object.toJSON(arg) + "' expected type " + validator); 
      } 
      break; 
    }   
}, 

/* 
* Validates that each option attribute in the given options has a valid name and type. 
* @Param options - the options to validate. 
* @Param validOptions - the valid options hash with their validators: 
* validOptions = { 
*  onSuccess : 'function', 
*  timeout : function(value){...} 
* } 
*/ 
validateOptions : function (validOptions, options){ 
    if (! WL.Utils.isDevelopmentMode() || typeof options === 'undefined'){ 
     return; 
    } 
    for (var att in options){ 
     if (! validOptions[att]){ 
      throw new Error("Invalid options attribute '" + att + "', valid attributes: " + Object.toJSON(validOptions)); 
     } 
     try { 
      WL.Validators.validateArgument(options[att], validOptions[att]); 
     } 
     catch (e){ 
      throw new Error("Invalid options attribute '" + att + "'"); 
     } 
    } 
}, 

}; तो मैं इसका उपयोग की

उसके बारे में यहां कुछ उदाहरण:

isUserAuthenticated : function(realm) { 
WL.Validators.validateArgument(realm, 'string'); 



getLocation: function(options) {    
    WL.Validators.validateOptions{ 
     onSuccess: 'function', 
     onFailure: 'function'}, options); 


makeRequest : function(url, options) { 
    WL.Validators.validateArray(arguments, ['string', 
     WL.Validators.validateOptions.carry({ 
     onSuccess : 'function', 
     onFailure : 'function', 
     timeout : 'number'})]); 
+0

यह एक अच्छा विचार है। इसके शीर्ष पर, आप अपने तर्कों को सत्यापित करने के लिए एक समारोह को 'सजाने' भी कर सकते हैं, और मूल कार्य 'साफ' छोड़ सकते हैं। – xtofl

-6

मान्य नहीं है। अधिक कोड उपयोगकर्ता को डाउनलोड करने के लिए अधिक कोड है, इसलिए यह उपयोगकर्ता और उत्पादन प्रणालियों पर एक बहुत ही वास्तविक लागत है। डेवलपर द्वारा पकड़ने के लिए तर्क त्रुटियां काफी आसान हैं; इस तरह के उपयोगकर्ता को बोझ मत करो।

+0

मैं सहमत नहीं है कि इस दृष्टिकोण है हमेशा सर्वोत्तम यदि एपीआई पर्याप्त जटिल है, तो कोई सत्यापन नाराज त्रुटियों का कारण बन सकता है। उदाहरण के लिए, एक्स्टजेस लाइब्रेरी का उपयोग करते समय कई बार ऐसा हुआ है कि मैं कामना करता हूं कि उन्होंने इनकमिंग पैरामीटर के अधिक सत्यापन किए हैं, मुझे सिरदर्द के घंटे बचाते हैं। – jvenema

+1

आपके पास कौन सा होगा? सिरदर्द के घंटे, या कोई उपयोगकर्ता नहीं क्योंकि आपकी साइट को लोड करने में बहुत लंबा समय लगता है? पसंद स्पष्ट है। –

+0

न तो यहां कोई विकल्प है। अपने कंप्रेसर और/या निर्माण प्रक्रिया को थोड़ा "स्मार्ट" बनाने के लिए आगे थोड़ा और काम करना मतलब है कि सड़क पर कोई सिरदर्द नहीं है, और आपके उपयोगकर्ताओं के लिए बहुत तेज लोड समय है। – jvenema

9

आपको यह तय करने का अधिकार है कि "रक्षात्मक" बनाम "अनुबंध" एपीआई बनाना है या नहीं। कई मामलों में, लाइब्रेरी के मैनुअल को पढ़ने से यह उपयोगकर्ता के लिए स्पष्ट हो सकता है कि उसे इस के तर्क या उस प्रकार की बाधाओं का पालन करना चाहिए।

यदि आप एक बहुत ही सहज, उपयोगकर्ता के अनुकूल, एपीआई बनाने का इरादा रखते हैं, तो कम से कम डीबग मोड में, अपने तर्कों को मान्य करना अच्छा होगा। हालांकि, सत्यापन लागत समय (और स्रोत कोड => स्थान), इसलिए इसे छोड़ना भी अच्छा हो सकता है।

यह आपके ऊपर है।

0

यह निर्भर करता है। यह पुस्तकालय कितना बड़ा होगा? ऐसा कहा जाता है कि जटिल एपीआई के साथ बड़ी परियोजनाओं के लिए टाइप की गई भाषाएं बेहतर होती हैं। चूंकि जेएस कुछ हद तक हाइब्रिड है, इसलिए आप चुन सकते हैं।

सत्यापन के बारे में - मुझे रक्षात्मक प्रोग्रामिंग पसंद नहीं है, फ़ंक्शन के उपयोगकर्ता को वैध तर्क पारित करने के लिए बाध्य किया जाएगा। और कोड मामलों के जेएस आकार में।

7

जितना हो सके उतना मान्य करें और उपयोगी त्रुटि संदेशों को मुद्रित करें जो लोगों को समस्याओं को जल्दी और आसानी से ट्रैक करने में मदद करते हैं।

कुछ विशेष टिप्पणियों (जैसे //+++VALIDATE और //--VALIDATE) के साथ इस सत्यापन कोड को उद्धृत करें ताकि आप इसे उच्च गति, संपीड़ित उत्पादन संस्करण के लिए आसानी से टूल के साथ हटा सकें।

+3

उत्पादन में विफलता के लिए उच्च गति? –

+2

उत्पादन कोड में, असफलता अक्सर प्रारंभिक नहीं होती है क्योंकि अधिकांश बग तय किए जाते हैं। उस ने कहा, यदि आप मेरे दृष्टिकोण का उपयोग करते हैं, तो आप आसानी से धीमे, सत्यापन संस्करण बना सकते हैं और यदि आपको आवश्यकता हो तो इसे उत्पादन में तैनात कर सकते हैं। –

0

जब मैंने अतीत में इस तरह के एपीआई विकसित किए हैं, तो मैंने कुछ भी मान्य किया है जो मुझे लगता है कि एक "प्रमुख" आवश्यकता है - आपके उदाहरण में, मैं पहले दो तर्कों को सत्यापित करता हूं।

जब तक आप समझदार डिफ़ॉल्ट निर्दिष्ट करते हैं, तो यह आपके उपयोगकर्ता के लिए यह निर्धारित करना बहुत आसान होना चाहिए कि "वैकल्पिक" तर्क सही ढंग से निर्दिष्ट नहीं हैं, क्योंकि इससे एप्लिकेशन में कोई बदलाव नहीं आएगा, लेकिन सब कुछ अभी भी काम करेगा अच्छी तरह।

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

संपादित करें:

Here're कुछ मैं ऐसे मामलों में जहां सत्यापन के लिए आवश्यक है में क्या करना पसंद है क्या का उदाहरण। यह विशेष मामला बहुत सरल है; मैं शायद इसके लिए सत्यापन के साथ परेशान नहीं होगा, क्योंकि यह वास्तव में तुच्छ है। आपकी जरूरतों के आधार पर, कभी-कभी प्रकारों को बल देने का प्रयास सत्यापन से बेहतर होगा, जैसा कि पूर्णांक मान के साथ प्रदर्शित किया गया है।

मान लें विस्तार() एक समारोह है कि वस्तुओं विलीन हो जाती है है, और सहायक कार्यों मौजूद हैं:

var f = function(args){ 
     args = extend({ 
     foo: 1, 
     bar: function(){}, 
     biz: 'hello' 
     }, args || {}); 

     // ensure foo is an int. 
     args.foo = parseInt(args.foo); 

     //<validation> 
     if(!isNumeric(args.foo) || args.foo > 10 || args.foo < 0){ 
     throw new Error('foo must be a number between 0 and 10'); 
     } 

     if(!isFunction(args.bar)){ 
     throw new Error('bar must be a valid function'); 
     } 

     if(!isString(args.biz) || args.biz.length == 0){ 
     throw new Error('biz must be a string, and cannot be empty'); 
     } 
     //</validation> 
    }; 

संपादित करें 2:

आप इसका प्रयोग गलत वर्तनी से बचना चाहते हैं, तो आप या तो 1) स्वीकार कर सकते हैं और उन्हें फिर से असाइन करें या 2) तर्क गणना मान्य करें। विकल्प 1 आसान है, विकल्प 2 Object.extendStrict (जैसे, इस तरह से किया जा सकता है, हालांकि मैं निश्चित रूप से अपनी ही विधि में यह refactor चाहते हैं, कुछ) (उदाहरण के कोड डब्ल्यू/प्रोटोटाइप काम करता है):

var args = { 
    ar: '' 
}; 
var base = { 
    foo: 1, 
    bar: function(){}, 
    biz: 'hello' 
}; 
// save the original length 
var length = Object.keys(base).length; 
// extend 
args = Object.extend(base, args || {}); 
// detect if there're any extras 
if(Object.keys(args).length != length){ 
    throw new Error('Invalid argument specified. Please check the options.') 
} 
+0

कुछ मामलों में वैकल्पिक तर्कों को पहचानना कठिन होता है, उदाहरण के लिए मैंने देखा कि यदि टाइमआउट मान एक स्ट्रिंग '60' था - कोई टाइमआउट सेट नहीं किया गया था (मान प्रोटोटाइप.जेएस .. को पास किया गया था ..)। क्या वैकल्पिक गुणों को हमेशा मान्य करना हमेशा संभव है? मैंने देखा कि prototype.js कभी-कभी अतिरिक्त विधियां जोड़ते हैं, तो डेवलपर द्वारा निर्धारित गलत-नामित विधियों को अलग कैसे कर सकते हैं? – Totach

+0

बिल्कुल, वे निश्चित रूप से पता लगाने में कठिन हो सकते हैं; मान्य करने के लिए और अधिक कारण। मैंने कुछ उदाहरण देने के लिए अपना जवाब अपडेट कर लिया है। – jvenema

0

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

1

आप अनुबंध द्वारा दोनों प्रविष्टि (तर्क) और निकास (वापसी) अंक मान्य कर सकते हैं। यहाँ एक lib https://www.npmjs.com/package/bycontract कि एक अनुबंध के लिए JSDoc वाक्य रचना स्वीकार करते हैं:

/** 
* @param {number|string} sum 
* @param {Object.<string, string>} payload 
* @param {function} cb 
* @returns {HTMLElement} 
*/ 
function foo(sum, payload, cb) { 
    // Test if the contract is respected at entry point 
    byContract(arguments, [ "number|string", "Object.<string, string>", "function" ]); 
    // .. 
    var res = document.createElement("div"); 
    // Test if the contract is respected at exit point 
    return byContract(res, "HTMLElement"); 
} 
// Test it 
foo(100, { foo: "foo" }, function(){}); // ok 
foo(100, { foo: 100 }, function(){}); // exception 

हालांकि मैं देव/परीक्षण/स्टेजिंग परिवेश पर यह मान्य रखने के लिए, लेकिन लाइव पर इसे छोड़:

if (env === "production") { 
    byContract.isEnabled = false; 
} 
संबंधित मुद्दे