ग्राफकॉल में इनपुट प्रकार की क्या बात है?


90

क्या आप बता सकते हैं कि यदि उत्परिवर्तन का इनपुट तर्क है तो यह इनपुट प्रकार क्यों होना चाहिए ? मुझे लगता है कि बहुत सरल बस आईडी प्रदान किए बिना पुन: उपयोग प्रकार

उदाहरण के लिए:

type Sample {
  id: String
  name: String
}

input SampleInput {
  name: String
}

type RootMutation {
  addSample(sample: Sample): Sample  # <-- instead of it should be
  addSample(sample: SampleInput): Sample
}

यह छोटी वस्तु के लिए ठीक है, लेकिन जब आपके पास स्कीमा में 10+ संपत्तियों के साथ बहुत सारे ऑब्जेक्ट होते हैं जो एक बोझ बन जाएगा।


32
इनपुट ऑब्जेक्ट को सीरियल करने योग्य होना चाहिए। क्योंकि आउटपुट ऑब्जेक्ट में चक्र हो सकते हैं, उन्हें इनपुट के लिए पुन: उपयोग नहीं किया जा सकता है।
जेसी बुकानन

1
जेसी, यह पर्याप्त जवाब की तरह लग रहा है! आप जवाब दे सकते हैं और मैं इसे चिह्नित करता हूं।
दिमित्री डस्किन

आश्चर्य है कि अगर इसके साथ इंटरफेस को जोड़ना संभव है
एमवीसीडीएस

जवाबों:


113

कल्पना से:

GraphQL ऑब्जेक्ट प्रकार (ObjectTypeDefinition) ... पुनः उपयोग के लिए अनुपयुक्त है [एक इनपुट के रूप में], क्योंकि ऑब्जेक्ट प्रकार में ऐसे फ़ील्ड हो सकते हैं जो तर्कों को परिभाषित करते हैं या इंटरफेस और यूनियनों के संदर्भ होते हैं, जिनमें से कोई भी इनपुट तर्क के रूप में उपयोग के लिए उपयुक्त नहीं है। । इस कारण से, सिस्टम में इनपुट ऑब्जेक्ट का एक अलग प्रकार है।

यह "आधिकारिक कारण" है, लेकिन कई व्यावहारिक कारण हैं कि आप किसी ऑब्जेक्ट प्रकार को इनपुट ऑब्जेक्ट प्रकार के रूप में उपयोग नहीं कर सकते हैं या इनपुट ऑब्जेक्ट प्रकार के रूप में ऑब्जेक्ट प्रकार का उपयोग नहीं कर सकते हैं:

कार्यक्षमता

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

दूसरे शब्दों में, यह दोहराव की तरह लग सकता है:

type Student {
  name: String
  grade: Grade
}

input StudentInput {
  name: String
  grade: Grade
}

लेकिन ऑब्जेक्ट प्रकारों या इनपुट ऑब्जेक्ट प्रकारों के लिए विशिष्ट सुविधाओं को जोड़ना यह स्पष्ट करता है कि वे अलग तरह से व्यवहार करते हैं:

type Student {
  name(preferred: Boolean): String
  grade: Grade
}

input StudentInput {
  name: String
  grade: Grade = F
}

सिस्टम सीमाएँ लिखें

GraphQL के प्रकारों को आउटपुट प्रकारों और इनपुट प्रकारों में वर्गीकृत किया जाता है ।

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

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

स्कीमा डिजाइन

अपने स्कीमा में एक इकाई का प्रतिनिधित्व करते समय, यह संभावना है कि कुछ संस्थाएं अपने संबंधित इनपुट और आउटपुट प्रकारों के बीच वास्तव में "फ़ील्ड साझा करेंगी":

type Student {
  firstName: String
  lastName: String
  grade: Grade
}

input StudentInput {
  firstName: String
  lastName: String
  grade: Grade
}

हालाँकि, ऑब्जेक्ट प्रकार (और वास्तव में अक्सर करते हैं) बहुत जटिल डेटा संरचनाओं को मॉडल कर सकते हैं:

type Student {
  fullName: String!
  classes: [Class!]!
  address: Address!
  emergencyContact: Contact
  # etc
}

हालांकि ये संरचनाएं उपयुक्त इनपुट में बदल सकती हैं (हम एक छात्र बनाते हैं, इसलिए हम भी उनके पते का प्रतिनिधित्व करने वाले ऑब्जेक्ट में पास करते हैं), अक्सर वे नहीं करते हैं - अर्थात शायद हमें कक्षा आईडी और अनुभाग आईडी द्वारा छात्र की कक्षाएं निर्दिष्ट करने की आवश्यकता है, न कि एक वस्तु। इसी तरह, हमारे पास ऐसे क्षेत्र हो सकते हैं, जिन्हें हम लौटना चाहते हैं, लेकिन म्यूट करना नहीं चाहते या इसके विपरीत (जैसे passwordक्षेत्र)।

इसके अलावा, यहां तक ​​कि अपेक्षाकृत सरल संस्थाओं के लिए, अक्सर हमारे पास ऑब्जेक्ट प्रकारों और उनके "समकक्ष" इनपुट ऑब्जेक्ट्स के बीच अशक्तता के आसपास विभिन्न आवश्यकताएं होती हैं। अक्सर हम यह गारंटी देना चाहते हैं कि प्रतिक्रिया में एक फ़ील्ड भी वापस किया जाएगा, लेकिन हम अपने इनपुट में उन्हीं फ़ील्ड को आवश्यक नहीं बनाना चाहते हैं। उदाहरण के लिए,

type Student {
  firstName: String!
  lastName: String!
}

input StudentInput {
  firstName: String
  lastName: String
}

अंत में, कई स्कीमाओं में, किसी दिए गए निकाय के लिए अक्सर ऑब्जेक्ट प्रकार और इनपुट ऑब्जेक्ट प्रकार के बीच एक-से-एक मैपिंग नहीं होती है। स्कीमा-स्तरीय इनपुट सत्यापन को और बेहतर बनाने के लिए अलग-अलग परिचालनों के लिए अलग-अलग इनपुट ऑब्जेक्ट प्रकारों का उपयोग करना एक सामान्य पैटर्न है:

input CreateUserInput {
  firstName: String!
  lastName: String!
  email: String!
  password: String!
}

input UpdateUserInput {
  email: String
  password: String
}

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


4
यह वास्तव में एक महान जवाब है!
चार्ली एनजी

सही है अगर मैं गलत हूं, लेकिन आपके उदाहरण Gradeमें, इनपुट में प्रकार का पुन: उपयोग नहीं किया जा सकता है StudentInput, है ना? आपको इनपुट ऑब्जेक्ट में या तो इनलाइन फ़ील्ड की आवश्यकता होगी या GradeInputइनपुट ऑब्जेक्ट की आवश्यकता होगी।
मैट

2
@ मैट अच्छा सवाल! उपरोक्त उदाहरण में, Gradeएक एनुम प्रकार है। ऑब्जेक्ट्स के विपरीत, स्केलर प्रकार (जैसे स्ट्रिंग, इंट, आदि) और एनम प्रकार का उपयोग इनपुट प्रकार और आउटपुट दोनों प्रकार के रूप में किया जा सकता है ।
डैनियल रियरडन

अच्छी व्याख्या
विशाख विजयन

बहुत बढ़िया जवाब!
जॉनी

25

जेसी की टिप्पणी सही है। अधिक औपचारिक उत्तर के लिए, यहाँ इनपुट प्रकारों पर ग्राफक्यूएल प्रलेखन का अंश दिया गया है :

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

अपडेट करें

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


4
यहाँ कुछ अधिक चर्चा है कि यह प्रतिबंध क्यों मौजूद है: github.com/graphql/graphql-js/issues/599
कैम जैक्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.