2015-05-31 12 views
10

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

उदाहरण के तौर पर मैं आईएमडीबी के समान गेम एपीआई पर काम कर रहा था लेकिन इसके बजाय वीडियो गेम के लिए।

यदि मैंने गेम से जुड़े सबकुछ वापस कर दिए हैं तो ऐसा कुछ दिखाई देगा।

/API/खेल/1

{ 
    "id": 1, 
    "title": "Call of Duty Advanced Warfare", 
    "release_date": "2014-11-24", 
    "publishers": [ 
     { 
      "id": 1, 
      "name": "Activision" 
     } 
    ], 
    "developers": [ 
     { 
      "id": 1, 
      "name": "Sledge Hammer" 
     } 
    ], 
    "platforms": [ 
     { 
      "id": 1, 
      "name": "Xbox One", 
      "manufactorer": "Microsoft", 
      "release_date": "2013-11-11" 
     }, 
     { 
      "id": 2, 
      "name": "Playstation 4", 
      "manufactorer": "Sony", 
      "release_date": "2013-11-18" 
     }, 
     { 
      "id": 3, 
      "name": "Xbox 360", 
      "manufactorer": "Microsoft", 
      "release_date": "2005-11-12" 
     } 
    ], 
    "esrbRating": { 
     "id": 1, 
     "code": "T", 
     "name": "Teen", 
     "description": "Content is generally suitable for ages 13 and up. May contain violence, suggestive themes, crude humor, minimal blood, simulated gambling and/or infrequent use of strong language." 
    }, 
    "reviews": [ 
     { 
      "id": 1, 
      "user_id": 111, 
      "rating": 4.5, 
      "description": "This game is awesome" 
     } 
    ] 
} 

हालांकि वे यह सब जानकारी की जरूरत नहीं है, लेकिन उसके बाद फिर से वे हो सकता है। सब कुछ के लिए कॉल करना I/O और प्रदर्शन से एक बुरा विचार लगता है।

मैंने अनुरोधों में पैरामीटर को निर्दिष्ट करके इसे करने के बारे में सोचा।

अब उदाहरण के लिए यदि आपने कोई निर्दिष्ट नहीं किया है तो आप सभी को वापस प्राप्त करना होगा।

{ 
    "id": 1, 
    "title": "Call of Duty Advanced Warfare", 
    "release_date": "2014-11-24" 
} 

हालांकि यह आप सभी जानकारी चाहते हैं कि आपके अनुरोध कुछ ऐसा दिखाई देंगे।

/api/game/1?include=publishers,developers,platforms,reviews,esrbRating 

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

मुझे लगता है कि नियंत्रक ऐसा कुछ दिखेंगे।

public @ResponseBody Game getGame(@PathVariable("id") long id, 
    @RequestParam(value = "include", required = false) String include)) { 

     // check which include params are present 

     // then someone do the filtering? 
} 

मुझे यकीन नहीं है कि आप वैकल्पिक रूप से गेम ऑब्जेक्ट को क्रमबद्ध कैसे करेंगे। क्या यह भी संभव है। स्प्रिंग एमवीसी में इस तक पहुंचने का सबसे अच्छा तरीका क्या है?

एफवाईआई, मैं स्प्रिंग बूट का उपयोग कर रहा हूं जिसमें क्रमशः जैक्सन शामिल है।

+0

लगता है कि आपने कुछ समय से पहले अनुकूलन यहाँ से करते हैं। क्या आपकी इकाई में वास्तव में इतना डेटा है कि आपको इसे ग्राहक के अनुरोध पर फ़िल्टर करने की आवश्यकता है? जो आपने दिखाया है उसके आधार पर, आप क्लाइंट और सर्वर दोनों को अत्यधिक जटिल करेंगे और आपकी आईओ की बचत नहीं करते समय आपकी सेवा की रीस्टफुलनेस तोड़ देंगे। –

+0

मेरे उदाहरण के मामले में, मैं सहमत हूं कि यह निश्चित रूप से अधिक है। आइए उदाहरण के लिए कहें कि यद्यपि गेम ऑब्जेक्ट का परिणाम एक विशाल JSON ऑब्जेक्ट में होगा, क्या आप कह रहे हैं कि/गेम/1/समीक्षाओं के बजाय/गेम/1/समीक्षा करना बेहतर होगा? = समीक्षा? – greyfox

+0

यदि ऑब्जेक्ट बहुत बड़ा है, तो मैं संग्रह को अलग-अलग सबसेर्स से अनुरोध करता हूं, क्योंकि कई अनुरोध जारी करने का ओवरहेड ट्रांसफर डेटा की कुल मात्रा के संबंध में छोटा होगा। –

उत्तर

9

Game ऑब्जेक्ट लौटने के बजाय, आप इसे Map<String, Object> के रूप में क्रमबद्ध कर सकते हैं, जहां नक्शा कुंजी विशेषता नामों का प्रतिनिधित्व करती है। तो आप include पैरामीटर के आधार पर अपने मानचित्र में मान जोड़ सकते हैं।

@ResponseBody 
public Map<String, Object> getGame(@PathVariable("id") long id, String include) { 

    Game game = service.loadGame(id); 
    // check the `include` parameter and create a map containing only the required attributes 
    Map<String, Object> gameMap = service.convertGameToMap(game, include); 

    return gameMap; 

} 

उदाहरण के लिए, यदि आप एक Map<String, Object> इस तरह है:

gameMap.put("id", game.getId()); 
gameMap.put("title", game.getTitle()); 
gameMap.put("publishers", game.getPublishers()); 

यह इस तरह धारावाहिक की जाएगी:

{ 
    "id": 1, 
    "title": "Call of Duty Advanced Warfare", 
    "publishers": [ 
    { 
     "id": 1, 
     "name": "Activision" 
    } 
    ] 
} 
+0

वाह वास्तव में एक सरल है और इसे संभालने के लिए बहुत लचीला तरीका है। – greyfox

+0

कस्टम सेवा के साथ ऐसा करना मेरे लिए बहुत अच्छा विचार नहीं है, क्या ऐसा करने का कोई "वसंत" तरीका है? – EralpB

+0

@EralpB आप यह भी खोज सकते हैं कि उनके नाम (जैक्सन का उपयोग करके) फ़ील्ड को क्रमबद्ध कैसे करें या ग्राफक्लुएल जैसे कुछ का उपयोग करें। इसके अलावा, मुझे यकीन नहीं है कि एक ही परिणाम प्राप्त करने के लिए "वसंत" तरीका है या नहीं। –

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