2012-09-04 7 views
11

Dato che Adwords è una cosa di Google, e Go è una cosa di Google, per quanto tempo finché non c'è una versione dell'API di AdWords scritta in Go?Come effettuare una chiamata SOAP in Go?

Associato a quella domanda, un altro: esistono ancora librerie SOAP per Go?

+1

Potrei facilmente effettuare chiamate SOAP andando semplicemente usando i pacchetti http e xml. –

+0

@dystroy: fai un buon punto. Comunque, sto appena iniziando in Go, quindi non è ancora una soluzione in quanto tale. – bugmagnet

+0

Vuoi che dettagli (in una risposta) come effettuare facilmente una chiamata SOAP in Go? –

risposta

1

Il Google APIs for Go è un work in progress.

+0

Non vedo ancora alcuna menzione di AdWords. Sei sicuro che sia coperto dalle attuali API di Google? – Timm

32

Posso rispondere all'API di AdWords poiché non ho visto alcun annuncio da parte dell'azienda e ho previsto il tempo prima che un rilascio non possa essere fatto dall'esterno.

Quindi risponderò alla tua seconda domanda.

Non conosco alcuna libreria SOAP in Go (go-lang.cat-v.org non sembra fare riferimento a uno) ma, come nella maggior parte delle lingue, un modo per trattare con semplici messaggi SOAP è quello di utilizzare i fondamentali http e xml librerie.

Le due operazioni importanti sono

1) per ottenere una risposta eseguendo una query POST:

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

2) per decodificare utilizzando un xml.NewDecoder nella struttura desiderata:

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

Ecco un esempio completo e commentato di una query SOAP eseguita 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

Nell'esempio precedente si sta utilizzando xml hardcoded c'è qualche pacchetto in cui è possibile generare il sapone xml – user2383973

+1

Chiamerei XML modello generato più di xml codificato. Si potrebbe tentare di generare l'XML con encoding/xml, ma si scoprirà rapidamente che ogni server vuole qualcosa di diverso, quindi nella mia esperienza, perlomeno, starai meglio armeggiando manualmente con l'XML fino a quando il server non risponderà come lo vuoi e poi lo stai semplicemente codificando, piuttosto che avere una libreria che genera per te e dover modificare la libreria fino a quando non genera ciò che vuoi costantemente. – semi

Problemi correlati