Bandwidth & Go
Agenda
- Why Go
- First Revisions
- Getting feedback
- Rolling in feedback
- Real world example
Why Go

Go & Communications
- High concurrency
- Fast
- Low Latency
- Strongly Typed


Concurrency
Fast

First Draft
Goals
- Copy popular SDK Design
- Idiomatic
- High API Coverage
Design Patterns
// CreateMessage sends a message (SMS/MMS)
// It returns ID of created message or error
func (api *Client) CreateMessage(data interface{}) (string, error) {
_, headers, err := api.makeRequest(http.MethodPost, api.concatUserPath(messagesPath), nil, data)
if err != nil {
return "", err
}
return getIDFromLocationHeader(headers), nil
}Getting Feedback
To Reddit!

Feedback
...I'm a bit wary of every response being returned map[string]interface{}. Usually they're marshaled into a struct...
have exported structs that we can use and avoid map[string]interface{}.
...look at the Stripe Go SDK for examples of how you can export your API responses as a struct. look at card.go and you'll see they have a struct with types for each field and they use tags to define how it marshals/unmarshals to json.
OK... v2.0
Design Patterns
// CreateMessageData struct
type CreateMessageData struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Text string `json:"text,omitempty"`
Media []string `json:"media,omitempty"`
CallbackURL string `json:"callbackUrl,omitempty"`
CallbackHTTPMethod string `json:"callbackHttpMethod,omitempty"`
FallbackURL string `json:"fallbackUrl,omitempty"`
CallbackTimeout int `json:"callbackTimeout,omitempty"`
ReceiptRequested string `json:"receiptRequested,omitempty"`
Tag string `json:"tag,omitempty"`
}
// CreateMessage sends a message (SMS/MMS)
// It returns ID of created message or error
func (api *Client) CreateMessage(data *CreateMessageData) (string, error) {
_, headers, err := api.makeRequest(http.MethodPost, api.concatUserPath(messagesPath), nil, data)
if err != nil {
return "", err
}
return getIDFromLocationHeader(headers), nil
}Examples
statuses, error := api.CreateMessages(
&bandwidth.CreateMessageData{From: "+19195551212", To: "+191955512141", Text:"Test1"},
&bandwidth.CreateMessageData{From: "+19195551212", To: "+191955512142", Text:"Test2"})api.CreateCall(&bandwidth.CreateCallData{From: "+19195551212", To: "+191955512142"})
Lessons Learned
- Go != Node
- Structs > interface
- Reddit actually good
- Maintainability?
- Swagger...
Putting it all together
Updating Call
api.UpdateCall(form.CallID, &bandwidth.UpdateCallData{
State: "transferring",
TransferTo: user.SIPURI,
TransferCallerID: callerID,
})Order Phone Number
numbers, err := api.client.GetAndOrderAvailableNumbers(bandwidth.AvailableNumberTypeLocal,
&bandwidth.GetAvailableNumberQuery{AreaCode: areaCode, Quantity: 1})
if err != nil {
return "", err
}
err = api.client.UpdatePhoneNumber(numbers[0].ID,
&bandwidth.UpdatePhoneNumberData{
ApplicationID: applicationID
})
github.com/bandwidthcom/go-bandwidth
github.com/BandwidthExamples/go-voice-reference-app
Questions?
Bandwidth & Go
By Daniel Tolbert
Bandwidth & Go
Slides for Go meetup in atlanta
- 761
