返回Go中的JSON

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

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对象一样。

这是我的代码:

  1. package main
  2. import "C"
  3. import (
  4. "encoding/json"
  5. "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
  6. )
  7. type Response struct {
  8. StatusCode int `json:"statusCode"`
  9. Headers map[string]string `json:"headers"`
  10. Body string `json:"body"`
  11. }
  12. func Handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
  13. res := &Response{
  14. StatusCode: 1,
  15. Headers: map[string]string{"Content-Type": "application/json"},
  16. Body: "Hello World",
  17. }
  18. content, _ := json.Marshal(res)
  19. return string(content), nil
  20. }

这是我从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:

  1. package main
  2. import "C"
  3. import (
  4. "encoding/json"
  5. "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
  6. )
  7. type Response struct {
  8. StatusCode int `json:"statusCode"`
  9. Headers map[string]string `json:"headers"`
  10. Body string `json:"body"`
  11. }
  12. func Handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
  13. res := &Response{
  14. StatusCode: 1,
  15. Headers: map[string]string{"Content-Type": "application/json"},
  16. Body: "Hello World",
  17. }
  18. content, _ := json.Marshal(res)
  19. return string(content), nil
  20. }

Here's the result I get from AWS:

返回Go中的JSON

答案1

得分: 9

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

  1. package main
  2. import (
  3. "github.com/aws/aws-lambda-go/lambda"
  4. )
  5. // Response ...
  6. type Response struct {
  7. StatusCode int `json:"statusCode"`
  8. Headers map[string]string `json:"headers"`
  9. Body string `json:"body"`
  10. }
  11. // Handle ...
  12. func Handle() (Response, error) {
  13. return Response{
  14. StatusCode: 1,
  15. Headers: map[string]string{"Content-Type": "application/json"},
  16. Body: "Hello World",
  17. },
  18. nil
  19. }
  20. func main() {
  21. lambda.Start(Handle)
  22. }

(下面的示例使用map[string]interface{}数据类型,无需创建type)

  1. package main
  2. import (
  3. "github.com/aws/aws-lambda-go/lambda"
  4. )
  5. // Handle ...
  6. func Handle() (map[string]interface{}, error) {
  7. return map[string]interface{}{
  8. "statusCode": 1,
  9. "headers": map[string]string{"Content-Type": "application/json"},
  10. "body": "Hello World",
  11. },
  12. nil
  13. }
  14. func main() {
  15. lambda.Start(Handle)
  16. }
英文:

Since AWS Lambda now officially supports Go, here is an revised example.

  1. package main
  2. import (
  3. "github.com/aws/aws-lambda-go/lambda"
  4. )
  5. // Response ...
  6. type Response struct {
  7. StatusCode int `json:"statusCode"`
  8. Headers map[string]string `json:"headers"`
  9. Body string `json:"body"`
  10. }
  11. // Handle ...
  12. func Handle() (Response, error) {
  13. return Response{
  14. StatusCode: 1,
  15. Headers: map[string]string{"Content-Type": "application/json"},
  16. Body: "Hello World",
  17. },
  18. nil
  19. }
  20. func main() {
  21. lambda.Start(Handle)
  22. }

<br>
(Update below with another example)

You can also just use a map[string]interface{} data type directly without having to create a type.

  1. package main
  2. import (
  3. &quot;github.com/aws/aws-lambda-go/lambda&quot;
  4. )
  5. // Handle ...
  6. func Handle() (map[string]interface{}, error) {
  7. return map[string]interface{}{
  8. &quot;statusCode&quot;: 1,
  9. &quot;headers&quot;: map[string]string{&quot;Content-Type&quot;: &quot;application/json&quot;},
  10. &quot;body&quot;: &quot;Hello World&quot;,
  11. },
  12. nil
  13. }
  14. func main() {
  15. lambda.Start(Handle)
  16. }

答案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:

确定