ruby-on-railsfastjsonapi

Rails - How to add pagination to Fastjson api?


The default result of rendering FastJsonApi gem serialized_json like below:

render json: FlashcardSerializer.new(flashcards).serialized_json

would be something like this:

{
 "data": [
    {
      "id": "1",
      "type": "flashcard",
      "attributes": {
        "question": "why?",
        "answer": "pretty good",
        "slug": null
      }
    },
    {
      "id": "2",
      "type": "flashcard",
      "attributes": {
        "question": "What is 0",
        "answer": "it is 0",
        "slug": null
       }
    }
  ]
}

I would rather add some extra information especially for pagination and I like the result to be something like this:

{
 "data": [
    {
      "id": "1",
      "type": "flashcard",
      "attributes": {
        "question": "why?",
        "answer": "pretty good",
        "slug": null
      }
    },
    {
      "id": "2",
      "type": "flashcard",
      "attributes": {
        "question": "What is 0",
        "answer": "it is 0",
        "slug": null
       }
    },
    "count":100,
     "page":1,
  ]
}

I am aware of other available gems that manage pagination in API, and I know how to do it without Fastjson. The main issue here is that is there any way to get the aforementioned result from this gem without changing a lot in the code. Thanks


Solution

  • The desired document would be invalid according to the JSON API specification. You would need to include next and previous links in a link section. The current and total_count would belong in the meta section.

    {
     "data": [
        {
          "id": "1",
          "type": "flashcard",
          "attributes": {
            "question": "why?",
            "answer": "pretty good",
            "slug": null
          }
        },
        {
          "id": "2",
          "type": "flashcard",
          "attributes": {
            "question": "What is 0",
            "answer": "it is 0",
            "slug": null
           }
        },
      ]
      "meta": {
        "page": { "current": 1, "total": 100 }
      },
      "links": {
        "prev": "/example-data?page[before]=yyy&page[size]=1",
        "next": "/example-data?page[after]=yyy&page[size]=1"
      },
    }
    

    Have a look at the JSON API specification before you continue designing the API.

    You can pass these information into the serializer as an options argument

    class FlashcardsController < ApplicationController
      def index
        render json: FlashcardSerializer.new(
          flashcards, { links: {}, meta: { page: { current: 1 } }
        ).serialized_json
      end
    end
    

    How you generate the data depends what you use to paginate.

    If you design a new API, I would also recommend to use cursor based pagination rather than offset pagination because of it's limitations.

    https://github.com/Netflix/fast_jsonapi#compound-document https://github.com/Netflix/fast_jsonapi/blob/master/spec/lib/object_serializer_spec.rb#L8-L32