2012-09-04 34 views
11

Cho rằng AdWords là một điều Google, và Go là một điều Google, bao lâu cho đến khi có một phiên bản của Adwords API được viết bằng Go?Làm thế nào để thực hiện cuộc gọi SOAP trong Go?

Được liên kết với câu hỏi đó, câu hỏi khác: có thư viện SOAP nào cho Go chưa?

+1

Tôi có thể dễ dàng thực hiện cuộc gọi SOAP bằng cách đơn giản bằng cách sử dụng gói http và xml. –

+0

@ dystroy: bạn thực hiện một điểm tốt. Tuy nhiên, tôi chỉ mới bắt đầu ở Go, vì vậy đó không phải là một giải pháp như vậy được nêu ra. – bugmagnet

+0

Bạn có muốn tôi chi tiết (trong câu trả lời) cách dễ dàng thực hiện cuộc gọi SOAP trong Go không? –

Trả lời

1

Google APIs for Go là một công việc đang được tiến hành.

+0

Tôi chưa thấy bất kỳ đề cập nào về AdWords. Bạn có chắc chắn rằng được bao gồm bởi các API Google hiện tại không? – Timm

32

Tôi có thể 'trả lời về API adwords khi tôi thấy không có thông báo từ công ty và dự đoán thời gian trước khi bản phát hành khó có thể thực hiện được từ bên ngoài.

Vì vậy, tôi sẽ trả lời câu hỏi thứ hai của bạn.

Tôi không biết thư viện SOAP nào trong Go (go-lang.cat-v.org dường như không tham chiếu) nhưng như trong hầu hết các ngôn ngữ, cách xử lý thư SOAP đơn giản là sử dụng thư viện cơ bản httpxml.

Hai hoạt động quan trọng là

1) để có được một câu trả lời bằng cách thực hiện một truy vấn POST:

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

2) để giải mã nó sử dụng một xml.NewDecoder vào cấu trúc mong muốn:

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

Dưới đây là ví dụ hoàn chỉnh và nhận xét về truy vấn SOAP được thực hiện trong 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

Trong ví dụ trên, bạn đang sử dụng xml được mã hóa cứng là có bất kỳ gói nào mà chúng tôi có thể tạo xà phòng xml – user2383973

+1

Tôi muốn gọi mẫu đó đã tạo XML hơn xml cứng. Bạn có thể cố gắng tạo XML bằng mã hóa/xml, nhưng bạn sẽ nhanh chóng thấy rằng mọi máy chủ đều muốn một cái gì đó khác nhau, vì vậy trong kinh nghiệm của tôi, ít nhất bạn tốt hơn là chỉ sử dụng XML theo cách thủ công cho đến khi bạn nhận được máy chủ phản hồi bạn muốn và sau đó chỉ cần hardcoding nó, thay vì có một thư viện tạo ra nó cho bạn và phải tinh chỉnh thư viện cho đến khi nó tạo ra những gì bạn muốn nhất quán. – semi

Các vấn đề liên quan