Go JSON:API(google/jsonapi)分页示例

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

Go JSON:API (google/jsonapi) Pagination Example

问题

可以有人展示一下如何使用 google/jsonapi 在响应中输出分页链接的示例吗?我尝试了几种方法,但都没有成功。我可以使用 MarshalPayload() 直接输出对象或对象数组,并通过使用 Linkable 接口将链接添加到节点上。但我还没有看到顶层对象的接口,所以这是我目前的实现。

	resp := map[string]interface{}{
		"data": users,
		"links": jsonapi.Links{
			"next": "next/2",
		},
	}

	c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
	err = jsonapi.MarshalPayload(c.Response(), resp)
	if err != nil {
		return echo.ErrInternalServerError
	}

报错信息是:
models should be a struct pointer or slice of struct pointers。我希望得到的输出结果类似于 JSON:API 主页 上的示例。例如:

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": ...<snipped>
}

谢谢。

英文:

Can someone show an example of how to output pagination links in the response using google/jsonapi? I've tried a couple approaches and none seems to work. I can directly output the object or an array of objects using MarshalPayload() and add links to the nodes by using the Linkable interface. I haven't yet seen an interface for the top level object so this is my current implementation.

		resp := map[string]interface{}{
			&quot;data&quot;: users,
			&quot;links&quot;: jsonapi.Links{
				&quot;next&quot;: &quot;next/2&quot;,
			},
		}

		c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
		err = jsonapi.MarshalPayload(c.Response(), resp)
		if err != nil {
			return echo.ErrInternalServerError
		}

Which is complaining that:
models should be a struct pointer or slice of struct pointers. The output I'm looking for is something similar to the one on the JSON:API Homepage. For example:

{
  &quot;links&quot;: {
    &quot;self&quot;: &quot;http://example.com/articles&quot;,
    &quot;next&quot;: &quot;http://example.com/articles?page[offset]=2&quot;,
    &quot;last&quot;: &quot;http://example.com/articles?page[offset]=10&quot;
  },
  &quot;data&quot;: ...&lt;snipped&gt;
}

TIA

答案1

得分: 0

我认为问题出在你的resp Map上。它需要是一个结构体。所以你需要像这样定义一个结构体:

type Resp struct {
    Data  []String `jsonapi:...`
    Links []Link   `jsonapi:...`
}

resp := new(Resp)

// 在这里将你的值添加到resp中
// 例如:resp.Data = users

c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
err = jsonapi.MarshalPayload(c.Response(), resp)
if err != nil {
    return echo.ErrInternalServerError
}

更新:

这是我的示例代码:

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

type Articles struct {
    Users []*User `jsonapi:"relation,users"`
}

处理函数:(我没有添加任何错误处理但你应该添加

```go
func (env *Env) TryJSONAPI(response http.ResponseWriter, request *http.Request) {
    resp := []*User{
        {ID: 3, Name: "username1"},
    }
    p, _ := jsonapi.Marshal(resp)
    payload, _ := p.(*jsonapi.ManyPayload)
    payload.Links = &jsonapi.Links{
        "self": fmt.Sprintf("https://example.com/articles"),
        "next": fmt.Sprintf("https://example.com/articles?page[offset]=%d", 2),
        "last": fmt.Sprintf("https://example.com/articles?page[offset]=%d", 10),
    }
    if err := json.NewEncoder(response).Encode(payload); err != nil {
        // 处理错误
    }
}

输出:

{
  "data": [
    {
      "type": "user",
      "id": "3",
      "attributes": {
        "name": "username1"
      }
    }
  ],
  "links": {
    "last": "https://example.com/articles?page[offset]=10",
    "next": "https://example.com/articles?page[offset]=2",
    "self": "https://example.com/articles"
  }
}
英文:

I think the issue is with your resp Map. That needs to be a struct. So you would need something like this:

type Resp struct {
    Data []String `jsonapi:...`
    Links []Link `jsonapi:...`
}

resp := new (Resp)

//here add your values to resp
//like: resp.Data = users 

c.Response().Header().Set(echo.HeaderContentType, jsonapi.MediaType)
err = jsonapi.MarshalPayload(c.Response(), resp)
if err != nil {
    return echo.ErrInternalServerError
}

UPDATE:

Here's my sample code:

type User struct {
	ID   int    `jsonapi:&quot;primary,user&quot;`
	Name string `jsonapi:&quot;attr,name&quot;`
}

type Articles struct {
	Users []*User `jsonapi:&quot;relation,users&quot;`
}

Handler function: (I didnt add any error handling, but you should)

func (env *Env) TryJSONAPI(response http.ResponseWriter, request *http.Request) {
	resp := []*User{
		{ID: 3, Name: &quot;username1&quot;},
	}
	p, _ := jsonapi.Marshal(resp)
	payload, _ := p.(*jsonapi.ManyPayload)
	payload.Links = &amp;jsonapi.Links{
		&quot;self&quot;: fmt.Sprintf(&quot;https://example.com/articles&quot;),
		&quot;next&quot;: fmt.Sprintf(&quot;https://example.com/articles?page[offset]=%d&quot;, 2),
		&quot;last&quot;: fmt.Sprintf(&quot;https://example.com/articles?page[offset]=%d&quot;, 10),
	}
	if err := json.NewEncoder(response).Encode(payload); err != nil {
		//handle error
	}
}

Output:

{
  data: [
    {
      type: &quot;user&quot;,
      id: &quot;3&quot;,
      attributes: {
        name: &quot;username1&quot;
      }
    }
  ],
  links: {
    last: &quot;https://example.com/articles?page[offset]=10&quot;,
    next: &quot;https://example.com/articles?page[offset]=2&quot;,
    self: &quot;https://example.com/articles&quot;
  }
}

huangapple
  • 本文由 发表于 2023年2月16日 10:22:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75467223.html
匿名

发表评论

匿名网友

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

确定