On Tue, Oct 24, 2017 at 1:55 AM, 'Ray Scott' via golang-nuts <golang-nuts@googlegroups.com> wrote: > > 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?
To be honest, to me your approach looks more like Node.JS than like Go. In Go, just write the simple blocking call. It would not be an overstatement to say that the entire Go language and toolchain is designed to make the simple blocking call efficient and effective. Using this approach does not require the users of your API to use channels, as you can, and should, use the channels within your function, and simply return the final value. From the user's perspective, it should look like a simple function call. Ian -- 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.