I'm currently writing a client library for accessing a backend API, 
everything is in
Go. From the Obj-C/Swift world that would look something like the first 
example
below,  where you'd pass a success and error closure to handle the 2 
outcomes.
The immediate error returned from the call would indicate something went 
wrong
while setting up or firing off the request, i.e. no network. This code would
typically sit inside a view controller that persisted between iterations of 
the
app's main run loop, and so blocking the main run loop was clearly frowned 
upon
as it would brick the app's interface while performing the http call.

// Example 1
// A handler function for each outcome
type CompletionHandler func(data []byte, response *Response)
type ErrorHandler func(err error, status ResponseMessageStatus, response 
*Response)

// The original Authenticate function signature
Authenticate(SASL string, mechanism SASLMechanismType, completionHandler 
CompletionHandler, errorHandler ErrorHandler) (err error)

// Using the API Call...
wg := sync.WaitGroup{}
wg.Add(1)

session := mypkg.New().NewSession()
err := session.Authenticate("saslvalue", mypkg.PlainSASLMechanismType, 
func(data []byte, response *mypkg.Response) {
// do something with data []byte

wg.Done()
}, func(err error, status mypkg.ResponseMessageStatus, response 
*mypkg.Response) {
//  handle err based on status value.
wg.Done()
})

wg.Wait()

// Alternate call setup:
err := session.Authenticate("saslvalue", mypkg.PlainSASLMechanismType, 
completeFunc, errorFunc)



The way I do it, the client need not worry about channels. I've read that
channels come with a performance cost. This API is actually interacting 
with a
websocket, so my response isn't just simply a single HTTP response 
returned, the
response object is quite complex and the 'data []byte' returned represents 
the
entire data part of all the response messages received.


// Example 2
// How I see more developers writing API client interfaces - it blocks by 
default.
res, err := session.Authenticate("saslvalue", mypkg.PlainSASLMechanismType)



The 2nd example, is what I see mostly in example blog posts with regard to
writing an API client in Go. Is my way idiomatic, or incorrect for some 
other
reason? I was considering channelling the data back to the calling 
goroutine,
but that's not an option because I have to wait until the final response 
message
status request in order to determine if the http operation ended 
successfully or
not. Plus I don't want users to have to deal with channels, even though 
they may
have to handle wait groups themselves.

I get that my way looks quite messy if you place the closures inline, but 
it's
actually very readable if you pass references to the closures/hanlders.

Any thoughts?







-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to