-
Notifications
You must be signed in to change notification settings - Fork 61
Controlling API output
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
.
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)
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.
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
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
})
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.
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.