Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Pagination access #64

Closed
Closed

Description

@gopherfortress

Great library thank you!

I wanted to ask, is there any way to access / unmarshal the pagination links that get sent by jsonapis like these:

"links": {
    "first": "http://somesite.com/movies?page[limit]=50&page[offset]=50",
    "prev": "http://somesite.com/movies?page[limit]=50&page[offset]=0",
    "next": "http://somesite.com/movies?page[limit]=50&page[offset]=100",
    "last": "http://somesite.com/movies?page[limit]=50&page[offset]=500"
 }

Ideally I'd like to provide access to these offsets in a separate struct as unmarshaling them into the Movie struct sounds strange! Thanks!

Activity

  1. aren55555 commented on Jan 25, 2017

    @aren55555
    Contributor

    @gopherfortress we recently added features to easily add "links" when serializing/marshaling. Unfortunately the same cannot be said for deserializing/unmarshaling.

    However there is still a way you can parse them out:

    func TestManyPayload_withLinks(t *testing.T) {
    	firstPageURL := "http://somesite.com/movies?page[limit]=50&page[offset]=50"
    	prevPageURL := "http://somesite.com/movies?page[limit]=50&page[offset]=0"
    	nextPageURL := "http://somesite.com/movies?page[limit]=50&page[offset]=100"
    	lastPageURL := "http://somesite.com/movies?page[limit]=50&page[offset]=500"
    
    	sample := map[string]interface{}{
    		"data": []interface{}{
    			map[string]interface{}{
    				"type": "posts",
    				"id":   "1",
    				"attributes": map[string]interface{}{
    					"body":  "First",
    					"title": "Post",
    				},
    			},
    			map[string]interface{}{
    				"type": "posts",
    				"id":   "2",
    				"attributes": map[string]interface{}{
    					"body":  "Second",
    					"title": "Post",
    				},
    			},
    		},
    		"links": map[string]interface{}{
    			KeyFirstPage:    firstPageURL,
    			KeyPreviousPage: prevPageURL,
    			KeyNextPage:     nextPageURL,
    			KeyLastPage:     lastPageURL,
    		},
    	}
    
    	data, err := json.Marshal(sample)
    	if err != nil {
    		t.Fatal(err)
    	}
    	in := bytes.NewReader(data)
    
    	payload := new(ManyPayload)
    	if err = json.NewDecoder(in).Decode(payload); err != nil {
    		t.Fatal(err)
    	}
    
    	if payload.Links == nil {
    		t.Fatal("Was expecting a non nil ptr Link field")
    	}
    
    	links := *payload.Links
    
    	first, ok := links[KeyFirstPage]
    	if !ok {
    		t.Fatal("Was expecting a non nil ptr Link field")
    	}
    	if e, a := firstPageURL, first; e != a {
    		t.Fatalf("Was expecting links.%s to have a value of %s, got %s", KeyFirstPage, e, a)
    	}
    }
  2. gopherfortress commented on Jan 25, 2017

    @gopherfortress
    Author

    Thanks for the answer!

    Any idea of the amount of work that is being done when doing the

    payload := new(ManyPayload)
    if err = json.NewDecoder(in).Decode(payload); err != nil {
    	t.Fatal(err)
    }
    

    My concern is that since links are at the very bottom of the document then it is possible that, assuming a big JSON document, twice the work will be done being done, once for decoding the pagination links and once for decoding the rest.

    Unfortunately the same cannot be said for deserializing/unmarshaling.

    Assuming there is indeed twice the work being done, any plans to support unmarshaling of pagination links?

    Thank you!

  3. aren55555 commented on Jan 25, 2017

    @aren55555
    Contributor

    @gopherfortress if all you are after is the "links" member there is definitely a more performant solution. The code sample I posted will traverse all of the "data" member which could be fairly lengthy. Take a look at our source code; I think you want to start by altering the OnePayload or ManyPayload to fit your use case of only parsing "links".

    As for fully supporting unmarshalling "links" that is a goal - however initial investigation leads me to believe adding such a feature (in a simple way) would mean breaking the existing unmarshal method signatures. We still need to put more thought into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions