2012-09-04 8 views
11

Da Adwords eine Google-Sache ist und Go eine Google-Sache, wie lange dauert es, bis eine Version der AdWords-API in Go geschrieben ist?Wie wird ein SOAP-Anruf in Go ausgeführt?

Mit dieser Frage verbunden, ein anderes: Gibt es noch SOAP-Bibliotheken für Go?

+1

Ich könnte einfach SOAP-Aufrufe in gehen, indem Sie einfach die http und Xml-Pakete. –

+0

@dystroy: Sie machen einen guten Punkt. Ich beginne aber erst in Go, also ist das noch keine Lösung. – bugmagnet

+0

Möchten Sie, dass ich (in einer Antwort) ausführlich darlege, wie man in Go einfach einen SOAP-Anruf durchführt? –

Antwort

1

Die Google APIs for Go ist ein work in progress.

+0

Ich sehe dort noch keine Erwähnung von AdWords. Sind Sie sicher, dass dies von den aktuellen Google APIs abgedeckt wird? – Timm

32

Ich kann 'über die Adwords-API beantworten, da ich keine Ankündigung von der Firma sah und die Zeit vorhersagte, bevor eine Veröffentlichung von außen kaum durchgeführt werden kann.

Also werde ich Ihre zweite Frage beantworten.

Ich kenne keine SOAP-Bibliothek in Go (go-lang.cat-v.org scheint nicht ein zu verweisen), sondern als in den meisten Sprachen, eine Möglichkeit, mit einfachen SOAP-Nachrichten zu behandeln ist, die grundlegenden http und xml Bibliotheken zu verwenden.

Die beiden wichtigen Operationen sind

1) eine Antwort zu erhalten, indem eine POST-Abfrage zu tun:

resp, err := httpClient.Post(query, "text/xml; charset=utf-8", someXMLasBytes) 

2) zu dekodieren es eine xml.NewDecoder in die gewünschte Struktur mit:

parser := xml.NewDecoder(bytes.NewBufferString(in)) 
err = parser.DecodeElement(&envelope, nil) 

Hier ist ein vollständiges und kommentiertes Beispiel für eine SOAP-Abfrage in Go (simplified from this):

package main 

import (
    "bytes" 
    "encoding/xml" 
    "fmt" 
    "io" 
    "io/ioutil" 
    "net/http" 
    "strings" 
) 

// The URL of the SOAP server 
const MH_SOAP_URL = "http://sp.mountyhall.com/SP_WebService.php" 

// this is just the message I'll send for interrogation, with placeholders 
// for my parameters 
const SOAP_VUE_QUERY_FORMAT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:tns=\"urn:SP_WebService\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" ><SOAP-ENV:Body><mns:Vue xmlns:mns=\"uri:mhSp\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><numero xsi:type=\"xsd:string\">%d</numero><mdp xsi:type=\"xsd:string\">%s</mdp></mns:Vue></SOAP-ENV:Body></SOAP-ENV:Envelope>" 

// Here I define Go structures, almost identical to the structure of the 
// XML message we'll fetch 
// Note that annotations (the string "return>item") allow to have a slightly 
// different structure or different namings 

type SoapItem struct { 
    Numero int 
    Nom  string 
    Type  string 
    PositionX int 
    PositionY int 
    PositionN int 
    Monde  int 
} 
type SoapVue struct { 
    Items []SoapItem "return>item" 
} 
type SoapFault struct { 
    Faultstring string 
    Detail  string 
} 
type SoapBody struct { 
    Fault   SoapFault 
    ProfilResponse SoapProfil 
    VueResponse SoapVue 
} 
type SoapEnvelope struct { 
    XMLName xml.Name 
    Body SoapBody 
} 

// Here is the function querying the SOAP server 
// It returns the whole answer as a Go structure (a SoapEnvelope) 
// You could also return an error in a second returned parameter 
func GetSoapEnvelope(query string, numero int, mdp string) (envelope *SoapEnvelope) { 
    soapRequestContent := fmt.Sprintf(query, numero, mdp) 
    httpClient := new(http.Client) 
    resp, err := httpClient.Post(MH_SOAP_URL, "text/xml; charset=utf-8", bytes.NewBufferString(soapRequestContent)) 
    if err != nil { 
     // handle error 
    } 
    b, e := ioutil.ReadAll(resp.Body) // probably not efficient, done because the stream isn't always a pure XML stream and I have to fix things (not shown here) 
    if e != nil { 
     // handle error 
    } 
    in := string(b) 
    parser := xml.NewDecoder(bytes.NewBufferString(in)) 
    envelope = new(SoapEnvelope) // this allocates the structure in which we'll decode the XML 
    err = parser.DecodeElement(&envelope, nil) 
    if err != nil { 
     // handle error 
    } 
    resp.Body.Close() 
    return 
} 
+0

Im obigen Beispiel verwenden Sie hardcoded xml gibt es ein Paket, wo wir die Soap xml generieren könnten – user2383973

+1

Ich würde diese Vorlage generiert XML mehr als hardcoded XML. Sie könnten versuchen, den XML-Code mit encoding/xml zu generieren, aber Sie werden schnell feststellen, dass jeder Server etwas anderes möchte. Daher ist es meiner Erfahrung nach besser, manuell mit dem XML-Code zu experimentieren, bis der Server reagiert Sie wollen und dann nur hart codieren, anstatt eine Bibliothek für Sie zu generieren und die Bibliothek zu optimieren, bis es konsistent erzeugt, was Sie wollen. – semi