Magento API'sine JavaScript ile yerel istemciden nasıl erişilir


9

Magento API'sına yerel bir JavaScript tabanlı uygulamadan (Titanium Desktop) erişmeniz ve bunu yapmanın en iyi yolunun ne olduğunu merak ediyorum.

Şimdiye kadar ne buldum:

Sorular:

  • Kimlik doğrulama mekanizmasını uygulama anahtarı ve sır ile HMAC tabanlı kimlik doğrulama gibi bir şeyle değiştirmek mümkün müdür? Kanıtlanmış çözümler bile var mı?
  • Değilse, OAuth Kullanıcı Aracısı Akışı Magento ile mümkün müdür? Belgeler bundan bahsetmiyor.
  • Yetkilendirme işleminin çoğunu kullanıcıdan gizlemek için kullanıcı kimlik bilgilerini AJAX (Çapraz Köşe İlkesi burada bir sorun değildir) ile göndermek mümkün müdür? Bu durumda erişim belirteci doğrudan yanıttan çıkarılabilir.

Tamam, ben REST çok odaklanmış olduğunu öğrendim, SOAP API benim sorunum çözmelidir, ancak JavaScript ile SOAP biraz hantal. Titanyum için bir kütüphane var ( github.com/kwhinnery/Suds ), deneyeceğim ve sonuçları buraya göndereceğim.
Fabian Schmengler

Yanıtlar:


8

Düzenleme: Daha iyi bir yol buldum, aşağıdaki Çözüm 2'ye bakın

Yorumda belirtildiği gibi, SOAP API'si gitmenin yoludur.

Çözüm 1:

Suds benim için hafif bir değişiklikle çalıştı ( Titanium.Network.HTTPClientyerine kullanım XMLHttpRequest), ancak çağrı için bir SOAP zarfı oluşturmaktan ve tüm XML yanıtını döndürmekten daha fazlası değil.

Kanıt-of-Concept uygulanması, jQuery kullanarak Ertelendi istek zincirleme için:

Service.MagentoClient = function()
{
    var self = this;
    var suds = new SudsClient({
        endpoint : "http://the-magento-host/api/v2_soap/",
        targetNamespace : "urn:Magento",
    });

    self.login = function() {
        var deferred = new $.Deferred();
        var args = {
            username : 'the-username',
            apiKey: 'the-api-key'
        };
        suds.invoke("login", args, function(xmlDoc) {
            self.sessionId = $(xmlDoc).find("loginReturn").text();
            deferred.resolve({});
            //TODO reject if no sessionid returned
        });
        return deferred;
    };

    self.setStatus = function(orderId, status, comment, notify) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject({ error: 'Login not successful.' });
            return;
        }
        var args = {
            sessionId        : self.sessionId,
            orderIncrementId : orderId,
            status           : status,
            comment          : comment,
            notify           : notify
        }
        suds.invoke("salesOrderAddComment", args, function(xmlDoc) {
            var success = $(xmlDoc).find("salesOrderAddCommentResponse").text();
            if (success) {
                deferred.resolve({});
            } else {
                deferred.reject({ error: 'Update not successful.' });
            }

        });
        return deferred;
    };
};

Kullanım örneği:

        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.setStatus('100000029', 'complete', 'soap test');
        }).then(function() {
            alert('Update successful');
        }, function(reject) {
            alert('Update failed: ' + reject.error);
        });

Çözüm 2:

Kendi API adaptörünü yazmanın gerçekten kolay olabileceği ortaya çıktı. Örneği ilebu çekirdek kesmek(ölü bağlantı) JSON-RPC adaptörü için temiz bir modül yazmayı başardım Zend_Json_Server. SOAP ve XML-RPC API'leriyle aynı Kimlik Doğrulama ve ACL'yi kullanır.

Giriş noktasını kullanmak için /api/jsonrpcyeni denetleyicinin apirotaya eklenmesi gerekir :

<config>
    <frontend>
        <routers>
            <api>
                <args>
                    <modules>
                        <my_jsonrpc before="Mage_Api">My_JsonRpc_Api</my_jsonrpc>
                    </modules>
                </args>
            </api>
        </routers>
    </frontend>
</config>

Güncelleme 02/2015: Yukarıdaki bağlantı şimdi öldü, bu yüzden JSON-RPC adaptörümü tam bir uzantı olarak açtım: https://github.com/sgh-it/jsonrpc

JS istemcim şimdi şöyle görünüyor (yine JQuery.Deferred ile, ancak API için ek 3. taraf kitaplıkları yok):

/**
 * Client for the Magento API
 */
Service.MagentoClient = function()
{
    var self = this;

    /**
     * @param string   method    the remote procedure to call
     * @param object   params    parameters for the RPC
     * @param callback onSuccess callback for successful request. Expects one parameter (decoded response object)
     * @param callback onError   callback for failed request. Expects one parameter (error message)
     * 
     * @return void
     */
    self.jsonRpc = function(method, params, onSuccess, onError) {
        var request = {
            method : method,
            params : params,
            jsonrpc : "2.0",
            id : 1
        };

        var options = {
            entryPoint : config.magentoClient.entryPoint,
            method: 'post',
            timeout: config.magentoClient.timeout
        };

        var httpClient = Titanium.Network.createHTTPClient();
        httpClient.onload = function(e) {
            try {
                var response = JSON.parse(this.responseText);
            } catch (jsonError) {
                return onError(jsonError);
            }
            if (response.error) {
                if (response.error.code == 5) { // session expired
                    self.sessionId = null;
                }
                return onError(response.error.message);
            }
            onSuccess(response);
        };
        httpClient.onerror = function(e) {
            onError(e.error + '; Response:' + this.responseText);
        };
        httpClient.setTimeout(options.timeout);

        if (httpClient.open(options.method, options.entryPoint)) {
            httpClient.setRequestHeader("Content-type", "application/json");
            httpClient.send(JSON.stringify(request));
        } else {
            onError('cannot open connection');
        }

    }
    /**
     * Retrieve session id for API
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.login = function() {
        var deferred = new $.Deferred();
        if (self.sessionId) {
            deferred.resolve();
            return deferred;
        }
        var loginParams = config.magentoClient.login;
        try {
            self.jsonRpc('login', loginParams, function(response) {
                if (response && response.result) {
                    self.sessionId = response.result;
                    deferred.resolve();
                } else {
                    deferred.reject('Login failed.');
                }
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }
        return deferred;
    };
    /**
     * Updates order states in Magento
     *
     * @param string method   name of the remote method
     * @param object args     arguments for the remote method
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.call = function(method, args) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject('No session.');
            return;
        }
        var callParams = {
            sessionId : self.sessionId,
            apiPath   : method,
            args      : args
        };
        try {
            self.jsonRpc('call', callParams, function(response) {
                deferred.resolve(response.result);
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }

        return deferred;
    };
};

Giriş yaptıktan sonra tüm yöntemlerin yönlendirildiğini unutmayın call. methodParametre gibi bir şeydir sales_order.list, argsparametre yöntemi bağımsız değişken ile, bir dizi ya da nesne.

Kullanım örneği:

        var filters = [];
        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.call('sales_order.list', [filters]).then(
                function(orders) {
                    // do something with the response
                }, function(error) {
                    alert('Magento API error: ' + error);
                }
            );
        });

Komut dosyanızdaki uç noktayı nasıl yapılandırırım?
Akrramo

Ön uç yönlendirici tanımını değiştirmeniz gerekiyor config.xml( apirotayı kullanmak istemiyorsanız , bunun yerine özel bir rota da kullanabilirsiniz, başka bir Magento modülünde yaptığınız gibi tanımlayabilirsiniz
Fabian Schmengler

Nerede bu kodu magento koyabilirsiniz
er.irfankhan11

Kurulum talimatları var: github.com/sgh-it/jsonrpc
Fabian Schmengler

Ve JavaScript kodu açıkça Magento'ya ait değil, harici istemciye ait
Fabian Schmengler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.