Return JSON in Go
Solution 1
https://play.golang.org/p/l2nrhG9lOA
It looks like the interface{}
return type is the culprit. Forcing that to a string
returns a more JSON-looking value. Having an interface{}
return type makes me think something else is expecting a struct
or marshal-able return value. Chase the interface{}
or force a string
and you should be good.
Solution 2
Since AWS Lambda now officially supports Go, here is an revised example.
package main
import (
"github.com/aws/aws-lambda-go/lambda"
)
// Response ...
type Response struct {
StatusCode int `json:"statusCode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
}
// Handle ...
func Handle() (Response, error) {
return Response{
StatusCode: 1,
Headers: map[string]string{"Content-Type": "application/json"},
Body: "Hello World",
},
nil
}
func main() {
lambda.Start(Handle)
}
(Update below with another example)
You can also just use a map[string]interface{}
data type directly without having to create a type
.
package main
import (
"github.com/aws/aws-lambda-go/lambda"
)
// Handle ...
func Handle() (map[string]interface{}, error) {
return map[string]interface{}{
"statusCode": 1,
"headers": map[string]string{"Content-Type": "application/json"},
"body": "Hello World",
},
nil
}
func main() {
lambda.Start(Handle)
}
frankgreco
Updated on June 04, 2022Comments
-
frankgreco almost 2 years
How to I get JSON back from golang without it being encoded as a string? I am using this project to wrap go code in python so that I can execute it in an AWS lambda function.
My issue is that whether I return
json.Marshal(obj)
orstring(json.Marshal(obj))
I either get the base64 encoded json or a string representation (e.g."{\"bar\": \"foo\"}"
). This is not an appropiate response if you are using the AWS API gateway as it expects pure json like you would get if you returned a json object in Node.js.Here's my code:
package main import "C" import ( "encoding/json" "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime" ) type Response struct { StatusCode int `json:"statusCode"` Headers map[string]string `json:"headers"` Body string `json:"body"` } func Handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) { res := &Response{ StatusCode: 1, Headers: map[string]string{"Content-Type": "application/json"}, Body: "Hello World", } content, _ := json.Marshal(res) return string(content), nil }
Here's the result I get from AWS:
-
frankgreco over 7 yearsI look at the source code for the dependency i'm using and the result is getting marshaled so it was getting marshaled twice
-
openwonk over 4 yearsIf working with API Gateway's Proxy Integration, see documentation for specifics on output format.
-
openwonk over 4 yearsSimilarly, if you get a "Malformed Lambda Response" error like this