如何使用google/jsonapi和echo框架返回有效的jsonapi响应。

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

How to return valid jsonapi response using google/jsonapi and echo framework

问题

下面的代码返回了两个连接在一起的JSON字符串,并且错误地使用了text/plain作为content-type。应该使用application/vnd.api+json

package main

import (
	"github.com/google/jsonapi"
	"github.com/labstack/echo"
	"net/http"
)

type Album struct {
	ID   int    `jsonapi:"primary,albums"`
	Name string `jsonapi:"attr,name"`
}

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		jsonapi.MarshalManyPayload(c.Response(), albumList())
		return c.JSON(http.StatusOK, c.Response())
	})
	e.Logger.Fatal(e.Start(":1323"))
}

func albumList() []*Album {
	a1 := Album{123, "allbum1"}
	a2 := Album{456, "allbum2"}
	albums := []*Album{&a1, &a2}
	return albums
}

错误的输出(两个连接在一起的JSON)。第一个是正确的jsonapi结构,我认为第二个与echo-framework有关:

{
  "data": [
    {
      "type": "albums",
      "id": "123",
      "attributes": {
        "name": "allbum1"
      }
    },
    {
      "type": "albums",
      "id": "456",
      "attributes": {
        "name": "allbum2"
      }
    }
  ]
}
{
  "Writer": {},
  "Status": 200,
  "Size": 133,
  "Committed": true
}

这段代码修复了问题,但看起来有些笨拙。我有一种感觉,使用echo可以更好地简化它。

e.GET("/", func(c echo.Context) error {
	var b bytes.Buffer
	body := bufio.NewWriter(&b)
	err := jsonapi.MarshalManyPayload(body, albumList())
	if err != nil {
		fmt.Println(err)
	}
	body.Flush()
	return c.JSONBlob(http.StatusOK, b.Bytes())
})

有什么想法吗?

英文:

The code bellow return a two concated JSON strings and a wrong content-type text/plain. Should be application/vnd.api+json

package main

import (
	"github.com/google/jsonapi"
	"github.com/labstack/echo"
	"net/http"
)

type Album struct {
	ID   int    `jsonapi:"primary,albums"`
	Name string `jsonapi:"attr,name"`
}

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		jsonapi.MarshalManyPayload(c.Response(), albumList())
		return c.JSON(http.StatusOK, c.Response())
	})
	e.Logger.Fatal(e.Start(":1323"))
}

func albumList() []*Album {
	a1 := Album{123, "allbum1"}
	a2 := Album{456, "allbum2"}
	albums := []*Album{&a1, &a2}
	return albums
}

faulty output (two concated jsons). The first is a correct jsonapi structure and I think the second is related to echo-framework:

{
  "data": [
    {
      "type": "albums",
      "id": "123",
      "attributes": {
	"name": "allbum1"
      }
    },
    {
      "type": "albums",
      "id": "456",
      "attributes": {
	"name": "allbum2"
      }
    }
  ]
}
{
  "Writer": {},
  "Status": 200,
  "Size": 133,
  "Committed": true
}

This code fix the problem but is seems awkward. I have the feeling there is a better way to facilitate it using echo.

e.GET("/", func(c echo.Context) error {
	var b bytes.Buffer
	body := bufio.NewWriter(&b)
	err := jsonapi.MarshalManyPayload(body, albumList())
	if err != nil {
		fmt.Println(err)
	}
	body.Flush()
	return c.JSONBlob(http.StatusOK, b.Bytes())
})

Any idea?

答案1

得分: 2

你的代码看起来没问题。不过可以简化一下:

var b bytes.Buffer // 这里可以使用缓冲池
err := jsonapi.MarshalManyPayload(&b, albumList())
if err != nil {
    return err
}
return c.JSONBlob(http.StatusOK, b.Bytes())

以下是几种不同的方法供你参考:

方法一:

c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
c.Response().WriteHeader(http.StatusOK)
return jsonapi.MarshalManyPayload(c.Response(), albumList())

方法二:

var b bytes.Buffer // 这里可以使用缓冲池
err := jsonapi.MarshalManyPayload(&b, albumList())
if err != nil {
    return err
}
c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
c.Response().WriteHeader(http.StatusOK)
_, err := b.WriteTo(c.Response())
return err
英文:

You're code looks alright. However it can be simplified-

var b bytes.Buffer // you could use buffer pool here
err := jsonapi.MarshalManyPayload(&b, albumList())
if err != nil {
    return err
}
return c.JSONBlob(http.StatusOK, b.Bytes())

Following approaches for your thoughts:

Approach 1 -

c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
c.Response().WriteHeader(http.StatusOK)
return jsonapi.MarshalManyPayload(c.Response(), albumList())

Approach 2 -

var b bytes.Buffer // you could use buffer pool here
err := jsonapi.MarshalManyPayload(&b, albumList())
if err != nil {
    return err
}
c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
c.Response().WriteHeader(http.StatusOK)
_, err := b.WriteTo(c.Response())
return err

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

发表评论

匿名网友

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

确定