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.