Skip to content

Controlling API output

Mat Ryer edited this page Jan 3, 2014 · 5 revisions

Goweb makes responding with data very easy via the responders.GowebAPIResponder object, a default instance which can be found at goweb.API which allows for this syntax:

err := goweb.API.RespondWithData(context, mydata)

Which, in JSON, will write out something like:

{
  "d": { "mydata": true },
  "s": 200
}

The response contains a d field, for data and an s field for status. If there were errors, they would be set to an array called e.

Formats

Thanks to the Codecs package, Goweb can output the content in any supported format requested by the client. If the client has an Accept header containing application/json, they'll get JSON, if it's text/xml it'll output XML.

If you want to be strict in what formats you support, you can create codecs/services.CodecService object, add only the codecs you want, and tell Goweb to use that service instead:

goweb.API.SetCodecService(s)

Enveloping

By default, all data payloads are enveloped. Which means they're wrapped in a consistent object that remains the same. You can control how this happens, and so can your clients.

Change the field names

If you want to change the field names for your enveloped responses you can do so by creating your own responders.GowebAPIResponder object, and changing the StandardField* variables.

// setup the API responder
apiResponder := NewGowebAPIResponder(goweb.CodecService, goweb.Respond)
apiResponder.StandardFieldDataKey = "data"
apiResponder.StandardFieldStatusKey = "status"
apiResponder.StandardFieldErrorsKey = "errors"
goweb.API = apiResponder

Transform the response before writing

Once the response has been prepared, Goweb will give a transformer function the chance to make some final tweaks before writing the response to the client.

To make use of this, just set your own function using the goweb.API.SetStandardResponseObjectTransformer method:

goweb.API.SetStandardResponseObjectTransformer(func(ctx context.Context, object map[string]interface{}) (map[string]interface{}, error) {

  // add our own thing to the object
  object["something"] = "123"

  // and return it
  return object, nil

})

Turn off enveloping altogether

Thanks to @pengux, you can turn off enveloping altogether. To do so, create your own responders.GowebAPIResponder and set AlwaysEnvelopResponse to false. Then tell Goweb to use your responder by setting it to the goweb.API variable.

// setup the API responder
apiResponder := NewGowebAPIResponder(goweb.CodecService, goweb.Respond)
apiResponder.AlwaysEnvelopResponse = false
goweb.API = apiResponder

Clients can still get the request enveloped (if they want to) by passing envelope=true as a query parameter along with the request.

Writing your own APIResponder

If you want to take complete control of how Goweb responds, you can write your own APIResponder implementation and assign it to the goweb.API variable.