JSP
JSP

Reputation: 571

Go JSON:API (google/jsonapi) Pagination Example

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{}{
            "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
        }

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:

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

TIA

Upvotes: 3

Views: 647

Answers (1)

Kaus2b
Kaus2b

Reputation: 845

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:"primary,user"`
    Name string `jsonapi:"attr,name"`
}

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

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: "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 {
        //handle error
    }
}

Output:

{
  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"
  }
}

Upvotes: 0

Related Questions