返回Go中的JSON

huangapple go评论77阅读模式
英文:

Return JSON in Go

问题

如何在golang中获取未编码为字符串的JSON?我正在使用这个项目将Go代码包装在Python中,以便在AWS Lambda函数中执行。

我的问题是,无论我返回json.Marshal(obj)还是string(json.Marshal(obj)),我都会得到Base64编码的JSON或字符串表示(例如"{\"bar\": \"foo\"}")。如果您正在使用AWS API网关,这不是一个合适的响应,因为它期望纯粹的JSON,就像在Node.js中返回JSON对象一样。

这是我的代码:

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
}

这是我从AWS得到的结果:

返回Go中的JSON

英文:

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:

返回Go中的JSON

答案1

得分: 9

由于AWS Lambda现在正式支持Go,这里是一个修订后的示例。

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)
}

(下面的示例使用map[string]interface{}数据类型,无需创建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)
}
英文:

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)
}

<br>
(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 (
	&quot;github.com/aws/aws-lambda-go/lambda&quot;
)

// Handle ...
func Handle() (map[string]interface{}, error) {
	return map[string]interface{}{
			&quot;statusCode&quot;: 1,
			&quot;headers&quot;:    map[string]string{&quot;Content-Type&quot;: &quot;application/json&quot;},
			&quot;body&quot;:       &quot;Hello World&quot;,
		},
		nil
}

func main() {
	lambda.Start(Handle)
}

答案2

得分: 2

看起来interface{}返回类型是问题的根源。将其强制转换为string会返回一个更像JSON的值。拥有interface{}返回类型让我想到其他地方可能期望一个struct或可序列化的返回值。追踪interface{}或者强制转换为string应该可以解决问题。

英文:

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.

答案3

得分: 0

json.Marshal返回的是一个纯粹的JSON字符串。看起来你正在使用%q来打印它。请参考https://play.golang.org/p/skvAfk-frO。

英文:

json.Marshal does return a pure JSON string. It looks like you're printing it with %q. See https://play.golang.org/p/skvAfk-frO.

huangapple
  • 本文由 发表于 2017年1月28日 05:13:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/41903075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定