rest मतलब क्या किसी को एक विश्वसनीय क्लाइंट का उदाहरण पता है जो हैटोस सिद्धांत का पालन करता है?




क्लाइंट सर्वर मॉडल क्या है (5)

मैंने जावा में एक बार और एक बार रुबी में दो हेटोएस क्लाइंट लिखे हैं और मैं आपकी निराशा साझा करता हूं। दोनों मौकों पर मैं जो कर रहा था उसके लिए टूलिंग समर्थन की कमी की पूरी कमी थी। उदाहरण के लिए, मैं जिस आरईएसटी एपीआई का उपयोग कर रहा था, वह मुझे बताएगा कि प्रत्येक हाइपरटेक्स्ट नियंत्रण के लिए किस HTTP विधि का उपयोग करना है, लेकिन HttpClient आपको विधि में गुजरने नहीं देता है, इसलिए मैं निम्नलिखित बदसूरत कोड (बीटीडब्ल्यू के भीतर सभी कोड रहता हूं) एक कस्टम चींटी कार्य, इसलिए BuildException एस):

private HttpMethod getHypermediaControl(Node href, Node method,
        NodeList children) {
    if (href == null) {
        return null;
    }
    HttpMethod control;
    if (method == null || method.getNodeValue().equals("")
            || method.getNodeValue().equalsIgnoreCase("GET")) {
        control = new GetMethod(href.getNodeValue());
    } else if (method.getNodeValue().equalsIgnoreCase("POST")) {
        control = new PostMethod(href.getNodeValue());
    } else if (method.getNodeValue().equalsIgnoreCase("PUT")) {
        control = new PutMethod(href.getNodeValue());
    } else if (method.getNodeValue().equalsIgnoreCase("DELETE")) {
        control = new DeleteMethod(href.getNodeValue());
    } else {
        throw new BuildException("Unknown/Unimplemented method "
                + method.getNodeValue());
    }
    control.addRequestHeader(accept);
    return control;
}

यह एक आरईएसटी क्लाइंट उपयोगिता विधियों का आधार है जो मैं उपयोग करता हूं।

private HttpMethod getHypermediaControl(String path, Document source)
        throws TransformerException, IOException {

    Node node = XPathAPI.selectSingleNode(source, path);
    return getHypermediaControl(node);
}

private HttpMethod getHypermediaControl(Node node) {
    if (node == null) {
        return null;
    }
    NamedNodeMap attributes = node.getAttributes();
    if (attributes == null) {
        return null;
    }
    Node href = attributes.getNamedItem("href");
    Node method = attributes.getNamedItem("method");
    HttpMethod control = getHypermediaControl(href, method,
            node.getChildNodes());
    return control;
}

private Document invokeHypermediaControl(HttpClient client, Document node,
        final String path) throws TransformerException, IOException,
        HttpException, URIException, SAXException,
        ParserConfigurationException, FactoryConfigurationError {
    HttpMethod method = getHypermediaControl(path, node);
    if (method == null) {
        throw new BuildException("Unable to find hypermedia controls for "
                + path);
    }
    int status = client.executeMethod(method);

    if (status != HttpStatus.SC_OK) {
        log(method.getStatusLine().toString(), Project.MSG_ERR);
        log(method.getResponseBodyAsString(), Project.MSG_ERR);
        throw new BuildException("Unexpected status code ("
                + method.getStatusCode() + ") from " + method.getURI());
    }
    String strResp = method.getResponseBodyAsString();
    StringReader reader = new StringReader(strResp);
    Document resp = getBuilder().parse(new InputSource(reader));
    Node rval = XPathAPI.selectSingleNode(resp, "/");
    if (rval == null) {
        log(method.getStatusLine().toString(), Project.MSG_ERR);
        log(method.getResponseBodyAsString(), Project.MSG_ERR);
        throw new BuildException("Could not handle response");
    }
    method.releaseConnection();
    return resp;
}

इस छोटे से कोड के साथ, मैं उन ग्राहकों को आसानी से लिख सकता हूं जो लौटाए गए दस्तावेज़ों में हाइपरमीडिया नियंत्रणों को पार करेंगे। गायब होने वाला मुख्य बिट फॉर्म पैरामीटर के लिए समर्थन है। सौभाग्य से मेरे लिए उपयोग किए जा रहे सभी नियंत्रण एक पैरामीटर रहित हैं (मैं रिफैक्टरिंग के संबंध में तीन के नियम का पालन ​​करता हूं)। पूर्णता के लिए यहां कोड कोड स्निपेट जैसा दिखता है:

    HttpMethod licenseUpdateMethod = getHypermediaControl(
            "/license/update", licenseNode);
    if (licenseUpdateMethod == null) {
        log(getStringFromDoc(licenseNode), Project.MSG_ERR);
        throw new BuildException(
                "Unable to find hypermedia controls to get the test suites or install the license");
    } else if (license != null) {
        EntityEnclosingMethod eem = (EntityEnclosingMethod) licenseUpdateMethod;
        Part[] parts = { new StringPart("license", this.license) };
        eem.setRequestEntity(new MultipartRequestEntity(parts, eem
                .getParams()));
        int status2 = client.executeMethod(eem);
        if (status2 != HttpStatus.SC_OK) {
            log(eem.getStatusLine().toString(), Project.MSG_ERR);
            log(eem.getResponseBodyAsString(), Project.MSG_ERR);
            throw new BuildException("Unexpected status code ("
                    + eem.getStatusCode() + ") from " + eem.getURI());
        }
        eem.releaseConnection();
    }

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

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

तो अब तक मुझे यह मुद्दा मिल रहा है कि हमें सभी को हमारी प्रतिष्ठित सेवाओं को लागू करना चाहिए जो प्रतिनिधित्व प्रदान करते हैं जो ग्राहकों को HATEOAS सिद्धांत का पालन करने में सक्षम HATEOAS है। और जब यह सब सिद्धांत में अच्छी समझ में आता है, तो मैं कुछ क्लाइंट कोड का एक अच्छा उदाहरण खोजने के लिए वेब को खराब कर रहा हूं जो इस विचार का सख्ती से पालन करता है।

जितना मैंने पढ़ा, उतना ही मुझे ऐसा महसूस करना शुरू हो रहा है कि यह अकादमिक चर्चा है क्योंकि वास्तव में कोई भी ऐसा नहीं कर रहा है! लोग डब्ल्यूएस- * स्टैक की कई त्रुटियों के बारे में पसंद करते हैं, लेकिन कम से कम यह स्पष्ट है कि ग्राहकों को कैसे लिखना है: आप डब्लूएसडीएल को पार्स कर सकते हैं और कोड उत्पन्न कर सकते हैं।

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

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

क्या कोई इस पर ग्राहक परिप्रेक्ष्य से कोई प्रकाश डाल सकता है? क्या कोई सही ढंग से गतिशील / प्रतिक्रियाशील रीस्टफुल क्लाइंट कोड का उदाहरण दिखा सकता है ताकि मुझे उन दर्शकों का विचार हो जो मैं वास्तव में लिख रहा हूं? (बेहतर अभी भी एक क्लाइंट एपीआई का एक उदाहरण है जो कुछ abstractions प्रदान करता है) अन्यथा यह सब सुंदर सैद्धांतिक ....

[संपादित करें: ध्यान दें, मुझे here एक समान प्रश्न मिला here , जो मुझे नहीं लगता कि वास्तव में उत्तर दिया गया था, लेखक को विकिपीडिया स्टब के साथ बंद कर दिया गया था!]


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

मैं अपने एक्सएमएल दस्तावेजों में शोर को कम करने के लिए सापेक्ष यूआरएल सक्षम करने के लिए एक्सएमएल: आधार का उपयोग करता हूं। छवियों को लोड करने के अलावा, और अन्य स्थिर डेटा मैं आमतौर पर केवल उपयोगकर्ता अनुरोधों पर लिंक का पालन करता हूं ताकि लिंक के प्रदर्शन ओवरहेड मेरे लिए महत्वपूर्ण न हों।

ग्राहकों पर, एकमात्र आम कार्यक्षमता जिसे मैंने बनाने की आवश्यकता महसूस की है, मेरे मीडिया प्रकारों और लिंक प्रबंधित करने के लिए एक वर्ग है।

अद्यतन करें:

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

डेटा माइनर

उदाहरण के लिए, एक पल के लिए कल्पना करें कि ट्विटर एपीआई वास्तव में रीस्टफुल था और मैं एक क्लाइंट लिखना चाहता था जो किसी विशेष ट्विटर उपयोगकर्ता के सबसे हालिया अनुयायी के हालिया स्टेटस संदेश को पुनः प्राप्त करेगा।

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

var twitterService = HttpClient.Get("http://api.twitter.com").Content.ReadAsTwitterService();

var userLink = twitterService.GetUserLink("DarrelMiller");
var userPage = HttpClient.Get(userLink).Content.ReadAsTwitterUserPage();

var followersLink = userPage.GetFollowersLink();
var followersPage = HttpClient.Get(followersLink).Content.ReadAsFollowersPage();
var followerUserName = followersPage.FirstFollower.UserName;

var followerUserLink = twitterService.GetUserLink(followerUserName);
var followerUserPage = HttpClient.Get(followerUserLink).Content.ReadAsTwitterUserPage();

var followerStatuses = HttpClient.Get(followerUserPage.GetStatusesLink()).Content.ReadAsTwitterUserPage();

var statusMessage = followerStatuses.LastMessage; 

डिस्पैचर

इस उदाहरण को बेहतर ढंग से चित्रित करने के लिए कल्पना करें कि आप एक ऐसे ग्राहक को कार्यान्वित कर रहे थे जिसने वंशावली की जानकारी प्रदान की। ग्राहक को पेड़ दिखाने, किसी विशेष व्यक्ति के बारे में जानकारी देने और संबंधित छवियों को देखने में सक्षम होना चाहिए। निम्न कोड स्निपेट पर विचार करें:

 void ProcessResponse(HttpResponseMessage response) {
            IResponseController controller;

            switch(response.Content.ContentType) {
                case "vnd.MyCompany.FamilyTree+xml":
                    controller = new FamilyTreeController(response);
                    controller.Execute();
                    break;
                case "vnd.MyCompany.PersonProfile+xml":
                    controller = new PersonProfileController(response);
                    controller.Execute();
                    break;
                case "image/jpeg":
                    controller = new ImageController(response);
                    controller.Execute();
                    break;
            }

        }

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

स्पष्ट रूप से ग्राहक आवेदन के लिए कई और टुकड़े हैं, लेकिन ये हैंटियोस के अनुरूप हैं। मुझे किसी भी बिंदु को स्पष्ट करने के लिए कहने के लिए स्वतंत्र महसूस करें क्योंकि मैंने कई विवरणों पर स्किम किया है।


पसंद का आपका वेब ब्राउजर पूरे डब्ल्यूडब्ल्यूडब्ल्यू में "शुद्ध हैटोज़" क्लाइंट है।

प्रश्न वास्तव में भावना इमो नहीं बना है।


नोकिया के स्थान एपीआई रीस्टफुल है और पूरे हाइपर्मिया का उपयोग करता है। यह यूआरआई टेम्पलेटिंग / हार्डकोडिंग के उपयोग को हतोत्साहित करने के लिए अपने दस्तावेज़ीकरण में भी स्पष्ट है:

Hypermedia लिंक का उपयोग

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


जिम, मैं हेटोआस के बाद एक विश्वसनीय ग्राहक के साथ उदाहरणों की कमी के साथ थोड़ा निराश था, इसलिए मैंने ब्लॉग पोस्ट लिखा था ताकि ऑर्डर बनाने और रखने के लिए उचित हेटोएस उदाहरण दिखाया जा सके। एपीआई के माध्यम से ऐसा करने के आश्चर्यजनक रूप से कुछ उदाहरण हैं और मुझे यह एक स्पर्श उलझन में मिला, लेकिन यहां लिंक है: एपीआई उदाहरण बाकी का उपयोग करना । मुझे बताएं कि आप क्या सोचते हैं और आपको क्या लगता है कि मैंने गलत किया है।







hateoas