Return JSON in Go

10,925

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)
}
Share:
10,925
frankgreco
Author by

frankgreco

Updated on June 04, 2022

Comments

  • frankgreco
    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) or string(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:

    enter image description here

  • frankgreco
    frankgreco over 7 years
    I look at the source code for the dependency i'm using and the result is getting marshaled so it was getting marshaled twice
  • openwonk
    openwonk over 4 years
    If working with API Gateway's Proxy Integration, see documentation for specifics on output format.
  • openwonk
    openwonk over 4 years
    Similarly, if you get a "Malformed Lambda Response" error like this