-1

I'm new to Go and working with a set of types generated by gowsdl based on the NetSuite SuiteTalk web service definition. It has created the following types:

type BaseRef struct {
    XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com BaseRef"`
    Name string `xml:"name,omitempty"`
}

type RecordRef struct {
    XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com   RecordRef"`
    *BaseRef
    InternalId string `xml:"internalId,attr,omitempty"`
    ExternalId string `xml:"externalId,attr,omitempty"`
    Type *RecordType `xml:"type,attr,omitempty"`
}

type GetRequest struct {
    XMLName xml.Name `xml:"urn:messages_2018_2.platform.webservices.netsuite.com GetRequest"`
    BaseRef *BaseRef `xml:"baseRef,omitempty"`
}

As I try to use these types it is unhappy in my ability to use the specific type of reference record in a GetRequest structure which is looking for a BaseRef which is what RecordRef is based on.

var partnerRecordType RecordType
partnerRecordType = RecordTypePartner
recordRef := RecordRef{
    Type:&partnerRecordType,
    InternalId:internalIdString,
}

var getRequest GetRequest
getRequest.BaseRef = &recordRef

The error I get is on the last line is:

cannot use &recordRef (type *RecordRef) as type *BaseRef in assignment

Any thoughts on how to proceed?

Colin Bowern
  • 2,152
  • 1
  • 20
  • 35
  • ***Go is not object-oriented.*** Go does not have classes, inheritance, or "base" types. If you're trying to use these concepts, or trying to approximate them in Go, stop. Look at your requirements and come at the problem using Go idioms, not the idioms of different languages. – Adrian Jan 04 '19 at 16:33
  • @Adrian - thanks, it looks like it is a design shortcoming of the gowsdl tool in how it handles WSDL's extension concept which is a form of inheritance. Likely need to look at how WSDL representation can be done with the Go idioms as you suggested. Beyond the scope of what I can invest in at this stage, so will look to roll this particular piece back into .NET Core which luckily AWS Lambda supports multiple function languages. – Colin Bowern Jan 07 '19 at 10:21
  • Even though go is not object-oriented, soap and go2wsdl can help us connect to netsuite with go. Even the object-oriented limitations are surmountable in this case. A full proof of concept is available at https://github.com/mk-j/go-netsuite-soap – velcrow Nov 14 '22 at 18:44

3 Answers3

1

Go does not support polymorphism in this way, neither does it support inheritance in way that say C# or Java does. Embedded structs are quite literally just embedded, they do not create a classical inheritance hierarchy. They simply give the wrapping struct all of the exposed methods and fields of the embedded struct (with some subtle caveats - check out the spec)

That said, in your example RecordRef is not related to BaseRef in terms of its type, instead it could be considered to "contain" a pointer to a BaseRef. In order for your program to compile, you will have explicitly assign the embedded BaseRef like so:

getRequest.BaseRef = &recordRef.BaseRef

As this code you are referencing has been auto generated from a WSDL, it may be a little cumbersome to update the GetRequest to provide a BaseRef like data structure in a more polymorphic, flexible fashion, but in order to do so you will need to use Go interfaces.

You could update the GetRequest to have a method with accepts in interface type, say XmlRef which would expose getters that can derive the data you need to assign to the GetRequest

For example

type XmlRef interface {
  Name() string
  InternalID() string
  ExternalID() string
}

func (r *GetRequest) SetRef(ref XmlRef) {
  r.BaseRef.Name = ref.Name()
  // etc...
}

Then simply implement the interface for RecordRef and any other structs that would need to be used in this context.

syllabix
  • 2,240
  • 17
  • 16
0

If I understand you right, you are looking for a method to access a struct's embbed field. You can simply use recordRef.BaseRef for that purpose.

Further reading: https://golang.org/ref/spec#Struct_types

leaf bebop
  • 7,643
  • 2
  • 17
  • 27
  • When I tried this the encoder doesn't pick up the body from the actual entity: Might need to do some further reading on how go works in this respects as suggested by @syllabix. – Colin Bowern Jan 04 '19 at 01:04
0

It is possible to connect to netsuite with the output of go2wsdl but many tweaks are required. A full proof of concept is available here: https://github.com/mk-j/go-netsuite-soap

But here are some examples of some of the tweaks required:

sed -i 's/urn:.*1.lists.webservices.netsuite.com //'  netsuite.go

Tweaking BaseRef and GetRequest:

type BaseRef struct {
    Name string `xml:"name,omitempty" json:"name,omitempty"`   
    InternalId string `xml:"internalId,attr,omitempty" json:"internalId,omitempty"`    
    ExternalId string `xml:"externalId,attr,omitempty" json:"externalId,omitempty"`    
    Type *RecordType `xml:"type,attr,omitempty" json:"type,omitempty"`    
    XsiType string `xml:"xsi:type,attr,omitempty"`
}
type GetRequest struct {
    XMLName xml.Name `xml:"get"`
    XmlNSXSI   string   `xml:"xmlns:xsi,attr"`
    XmlNSPC   string   `xml:"xmlns:platformCore,attr"`    
    BaseRef *BaseRef `xml:"baseRef,omitempty" json:"baseRef,omitempty"`
}

Then this code produced an successful xml response from the soap server:

recordType := netsuite.RecordTypePartner
baseRef :=netsuite.BaseRef{
        InternalId:"1234",
        Type:&recordType,
        XsiType:"platformCore:RecordRef",                
    }
request := netsuite.GetRequest{
    BaseRef:&baseRef,
    XmlNSXSI: "http://www.w3.org/2001/XMLSchema-instance",
    XmlNSPC:"urn:core_2022_1.platform.webservices.netsuite.com",
}
getResponse, err := service.Get(&request)

Which made the raw request:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header><tokenPassport>[redacted]</tokenPassport></soap:Header>
  <soap:Body>
    <get xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:platformCore="urn:core_2022_1.platform.webservices.netsuite.com">
      <baseRef internalId="1234" type="partner" xsi:type="platformCore:RecordRef"></baseRef>
    </get>
  </soap:Body>
</soap:Envelope>
  

Sources used: https://www.zuar.com/blog/netsuite-api-exploring-soap/

velcrow
  • 6,336
  • 4
  • 29
  • 21