नेस्ट रस्ट यूरल्स और पेरेंट आईडी, जो बेहतर डिज़ाइन है?


20

ठीक है, हमारे पास दो संसाधन हैं: Albumऔर Song। यहाँ एपीआई है:

GET,POST /albums
GET,POST /albums/:albumId
GET,POST /albums/:albumId/songs
GET,POST /albums/:albumId/songs/:songId

हम जानते हैं कि हम कुछ गीत से नफरत करते हैं, इसे कहा जाता है Susy, उदाहरण के लिए। हमें कहां searchकार्रवाई करनी चाहिए ?

एक और सवाल। ठीक है, अब यह अधिक वास्तविक है। हम एल्बम 1 खोलते हैं और सभी गाने लोड करते हैं। हम JS ऑब्जेक्ट्स बनाते हैं, प्रत्येक में गीत डेटा होता है और इसकी कुछ विधियाँ होती हैं जैसे: remove, update

सॉन्ग ऑब्जेक्ट में आईडी, नाम और सामान है, लेकिन इसका कोई सुराग नहीं है कि यह किस माता-पिता का है, क्योंकि हम क्वेरी के द्वारा गाने की सूची प्राप्त करते हैं और प्रत्येक के साथ माता-पिता के आईडी को वापस करना अच्छा नहीं होगा। क्या मै गलत हु?

इसलिए, मुझे कुछ उपाय दिखाई देते हैं, लेकिन मुझे यकीन नहीं है।

  1. पैरेंट आईडी को वैकल्पिक बनाएं - गेट-पैरामीटर के रूप में। यह दृष्टिकोण मैं वर्तमान में उपयोग करता हूं, लेकिन मुझे लगता है कि यह बदसूरत है।

    List,Create /songs?album=albumId
    Update,Delete /songs/:songId
    Get /songs/?name=susy # also, solution for first question
    
  2. हाइब्रिड। OPTIONSमेटा डेटा प्राप्त करने के लिए क्वेरी करने के लिए एल्बम आईडी की आवश्यकता होने के बाद से अब यह आसान है ।

    List,Create /album/:albumId/songs
    Update,Delete /songs/:songId
    POST /songs/search # also, solution for first question
    
  3. प्रत्येक संसाधन उदाहरण के साथ पूर्ण यूआरएल लौटें। एपीआई समान है, लेकिन हमें इस तरह गाने मिलेंगे:

    id: 5
    name: 'Elegy'
    url: /albums/2/songs/5
    

    मैंने सुना है कि इस दृष्टिकोण को HATEOAS कहा जाता है।

  4. इसलिए ... मूल आईडी प्रदान करने के लिए

    id: 5
    name: 'Elegy'
    albumId: 2
    

कौनसा अच्छा है? या शायद मैं गूंगा हूं? कुछ सलाह फेंको, दोस्तों!

जवाबों:


31

हमें खोज कार्रवाई कहां करनी चाहिए?

में GET /search/:text। यह एक JSON सरणी देता है जिसमें मैच होते हैं, हर मैच जिसमें वह एल्बम होता है। यह समझ में आता है, क्योंकि ग्राहक को ट्रैक में ही दिलचस्पी नहीं हो सकती है, लेकिन संपूर्ण एल्बम (कल्पना करें कि आप एक गीत की खोज कर रहे हैं, जिसे आप मानते हैं, उसी एल्बम में था जिसे आप नाम याद रखते हैं)।

प्रत्येक के साथ माता-पिता की आईडी वापस करना उतना अच्छा नहीं होगा। क्या मै गलत हु?

व्यक्तिगत ट्रैक में एल्बम हो सकता है। यह सुनिश्चित करेगा कि ट्रैक प्रतिनिधित्व एक समान है यदि आप किसी एल्बम के माध्यम से या खोज (यहां कोई एल्बम नहीं) के माध्यम से ट्रैक प्राप्त कर सकते हैं।

कौनसा अच्छा है?

जैसा कि पहले कहा गया है, एल्बम सहित समझ में आता है। जबकि तीसरा बिंदु (सापेक्ष यूआरआई के साथ) कुछ मामलों में दिलचस्प हो सकता है (आपको यूआरआई के गठन के तरीके के बारे में सोचने की ज़रूरत नहीं है), इसमें स्पष्ट रूप से एल्बम प्रदान नहीं करने का दोष है। चौथा बिंदु इसे सही करता है। यदि आपको प्रतिक्रिया में रिश्तेदार यूआरआई होने का लाभ दिखाई देता है, तो आप बिंदु 3 और 4 को जोड़ सकते हैं।

या शायद मैं गूंगा हूं?

अच्छे यूआरआई को चुनना एक आसान काम नहीं है, खासकर जब से एक भी सही उत्तर नहीं है। यदि आप एक ही समय में API के रूप में क्लाइंट विकसित करते हैं, तो यह आपको बेहतर तरीके से कल्पना करने में मदद कर सकता है कि एपीआई का उपयोग कैसे किया जा सकता है। यह कहा जा रहा है, अन्य लोग तब अन्य usages को पसंद कर सकते हैं जो आप API विकसित करते समय नहीं सोच रहे थे।

एक पहलू जो समस्याग्रस्त हो सकता है वह यह है कि आप डेटा को आंतरिक रूप से कैसे व्यवस्थित करते हैं, अर्थात एक पदानुक्रम का उपयोग। आपकी टिप्पणी से, आप सोच रहे हैं कि इसमें क्या प्रतिक्रिया होनी चाहिए GET /artist/1/album/10/song/3/comment/23, जो एक बहुत ही वृक्ष-उन्मुख दृष्टि दिखाती है। यह बाद में सिस्टम का विस्तार करते समय कुछ मुद्दों को जन्म दे सकता है। उदाहरण के लिए:

  • अगर किसी गीत में कोई एल्बम नहीं है तो क्या होगा?
  • क्या होगा अगर एक एल्बम में कई कलाकार हों?
  • क्या होगा यदि आप एक फीचर जोड़ना चाहते हैं जिससे एल्बमों पर टिप्पणी करना संभव हो सके?
  • अगर टिप्पणियों की टिप्पणी होनी चाहिए तो क्या होगा?
  • आदि।

यह अनिवार्य रूप से मेरे ब्लॉग में बताई गई समस्या है : एक पेड़ का प्रतिनिधित्व कई मामलों में प्रभावी रूप से उपयोग करने के लिए बहुत सी सीमाएं हैं।

यदि आप पदानुक्रम को नष्ट करते हैं तो क्या होता है? चलो देखते हैं।

  1. GET /albums/:albumIdएल्बम के बारे में मेटा जानकारी युक्त एक JSON देता है (जैसे कि जब यह प्रकाशित हुआ था या JPEG का URI एल्बम कवर दिखा रहा था) और पटरियों की एक सरणी। उदाहरण के लिए:

    GET /albums/151
    {
        "id": 151,
        "gid": "dbd3cec7-b927-423f-894b-742c4c7b54ce",
        "name": "Yellow Submarine",
        "year": 1969,
        "genre": "Psychedelic rock",
        "artists": ["John Lennon", "Paul McCartney", ...],
        "tracks": [
            {
                "id": 90224,
                "title": "Yellow Submarine",
                "length": "2:40"
            },
            {
                "id": 83192,
                "title": "Only a Northern Song",
                "length": "3:24"
            }
            ...
        ]
    }

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

  2. GET /tracks/:trackIdकिसी विशिष्ट ट्रैक के बारे में जानकारी देता है। चूंकि अब कोई पदानुक्रम नहीं है, आपको एल्बम या कलाकार का अनुमान लगाने की आवश्यकता नहीं है: केवल एक चीज जिसे आपको वास्तव में जानना है, वह ट्रैक का पहचानकर्ता है।

    या शायद नहीं भी? क्या होगा यदि आप इसे नाम से निर्दिष्ट कर सकते हैं GET /tracks/:trackName?

    GET /tracks/Only%20a%20Northern%20Song
    {
        "id": 83192,
        "gid": "8d9c4311-9d7b-40a4-8aeb-4fe96247fe2b",
        "title": "Only a Northern Song",
        "writers": ["George Harrison"],
        "artists": ["John Lennon", "Paul McCartney", "Ringo Starr"],
        "length": "3:24",
        "record-date": 1967,
        "albums": [151, 164],
        "soundtrack": {
            "uri": "http://audio.example.com/tracks/static/83192.mp3",
            "alias": "Beatles - Only a Northern Song.mp3",
            "length-bytes": 3524667,
            "allow-streaming": true,
            "allow-download": false
        }
    }

    अब करीब से देखो albums; आप क्या देखते हैं? राइट, एक नहीं, बल्कि दो एल्बम। यदि आपके पास पदानुक्रम है, तो आप ऐसा नहीं कर सकते (जब तक कि आप रिकॉर्ड की नकल न करें)।

  3. GET /comments/:objectGid। आप प्रतिक्रियाओं में बदसूरत GUIDs देखा हो सकता है। उन GUID को कार्यों के प्रदर्शन के लिए डेटाबेस में इकाई की पहचान करना संभव बनाता है, जो एल्बम, या कलाकार या ट्रैक्स पर लागू किया जा सकता है। जैसे कमेंट करना।

    GET /comments/8d9c4311-9d7b-40a4-8aeb-4fe96247fe2b
    [
        {
            "author": {
                "id": 509931,
                "display-name": "Arseni Mourzenko"
            },
            "text": "What a great song! (And I'm proud of the usefulness of my comment)",
            "concerned-object": "/tracks/83192"
        }
    ]

    टिप्पणी संबंधित वस्तु को संदर्भित करती है, जिससे उसके संदर्भ के बाहर की टिप्पणी तक पहुंचना संभव हो जाता है (उदाहरण के लिए नवीनतम टिप्पणियों को मॉडरेट करते समय GET /comments/latest)।

ध्यान दें कि इसका मतलब यह नहीं है कि आपको अपने एपीआई में पदानुक्रम के किसी भी रूप से बचना चाहिए। ऐसे मामले हैं जहां यह समझ में आता है। निर्धारित नियम के रूप में:

  • यदि संसाधन को उसके मूल संसाधन के संदर्भ में कोई मतलब नहीं है, तो पदानुक्रम का उपयोग करें।

  • यदि संसाधन विभिन्न प्रकारों के मूल संसाधनों के संदर्भ में (1) अकेले या (2) रह सकते हैं या (3) कई माता-पिता हैं, तो पदानुक्रम का उपयोग नहीं किया जाना चाहिए।

उदाहरण के लिए, फ़ाइल की पंक्तियाँ फ़ाइल के संदर्भ के बाहर कोई अर्थ नहीं रखती हैं, इसलिए:

GET /file/:fileId

तथा:

GET /file/:fileId/line/:lineIndex

ठीक है।


हां, खोज से, मैं पूरी एल्बम जानकारी भी वापस कर सकता हूं, यह एक और संसाधन बना देगा - SongSearchResultयह ठीक है, मुझे लगता है। लेकिन URL के बारे में क्या है? क्या मुझे parentIDप्रत्येक वस्तु प्रदान करनी चाहिए और इसे GET- पैरामीटर या url के सामान्य भाग के रूप में उपयोग करना चाहिए ? अगर मुझे गहराई> 2 हो तो क्या होगा? /artist/1/album/10/song/3/comment/23- यह commentऑब्जेक्ट में कलाकार, एल्बम और गीत की हर आईडी प्रदान करने के लिए पागल है , लेकिन मैंने सुना है कि यह जाने का एक तरीका है, लेकिन dsigusting नहीं है ?!
dt0xff

@ dt0xff: मैंने अपना उत्तर संपादित किया। मुझे लगता है कि अब आपको यह स्पष्ट रूप से बताना चाहिए कि गहराई से कैसे बचा जा सकता है।
आर्सेनी मूरज़ेंको

हाँ, अब यह स्पष्ट है कि प्रत्येक संसाधन के लिए प्रविष्टि-बिंदु को लागू करना बहुत आसान है (कुछ लाइन या अन्य कार्यात्मक चीज़ों को छोड़कर) w / o इसे माता-पिता से url में जोड़कर। धन्यवाद, आपने मुझे आश्वस्त किया कि मेरी पसंद सही थी और "सामान्य दृष्टिकोण" (वास्तव में, कई नेस्टेड चीजें .. restangularउस पर बनाया गया है) यह अच्छा नहीं है।
dt0xff

बहुत बढ़िया जवाब। मुझे हालांकि कुछ आपत्तियां हैं। "क्या होगा अगर एक एल्बम में कई कलाकार हैं?" विभिन्न यूआरआई द्विआधारी संबंध यूआरआई के बाद से एक ही संसाधन की पहचान कर सकते हैं -> संसाधन सही-अद्वितीय है (कई-से-एक)। तो यूआरआई /artists/foo/albums/quxऔर /artists/bar/albums/quxपूरी तरह से एक ही एल्बम संसाधन की पहचान कर सकते हैं। दूसरे शब्दों में, एक यूआरआई में पथ घटक एक ग्राफ पदानुक्रम का प्रतिनिधित्व करता है, जरूरी नहीं कि एक पेड़ पदानुक्रम है, जो इसे न केवल श्रेणियों का प्रतिनिधित्व करने के लिए उपयुक्त बनाता है, बल्कि टैग भी करता है।
मैगीयरो

1
... "यह अनिवार्य रूप से मेरे ब्लॉग में बताई गई समस्या है : एक पेड़ के प्रतिनिधित्व की बहुत सी सीमाएँ हैं जो कई मामलों में प्रभावी रूप से उपयोग की जाती हैं।" तो नहीं, यह कोई समस्या नहीं है। "क्या होगा यदि आप एक ऐसी सुविधा जोड़ना चाहते हैं जिससे एल्बमों पर टिप्पणी करना संभव हो सके?" यह एक समस्या नहीं है: या तो /artists/foo/albums/qux/comments/7। "क्या होगा अगर टिप्पणियों की टिप्पणियां होनी चाहिए?" इसी तरह: /artists/foo/albums/qux/song/5/comments/2/comments/8
मैगीयरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.