1

I'm battling with my JSON rendering. I want to comply with the simple JSend response format.

Basically what I want is the status and the data in my response.

I've set up my Serializer default adapter to json :

ActiveModelSerializers.config.adapter = :json

My serializer is simple :

class RecordSerializer < ActiveModel::Serializer
  attributes :id, :raw
end

So when I do this :

record_list = @current_user.records
render json: record_list

I got this :

{
    "records": [
        {
            "id": 1,
            "raw": "aaa"
        },
        {
            "id": 2,
            "raw": "bbb"
        }
    ]
}

Now the tricky part, if I want to add a data key on top, it override my records key instead of adding it on top.

render json: record_list, root: "data"

Give this :

{
    "data": [
        {
            "id": 1,
            "raw": "aaa"
        },
        {
            "id": 2,
            "raw": "bbb"
        }
    ]
}

Also, how can I add other keys like the status key ? As soon as I create a custom Hash, the serializer is ignored. So for example this :

render json: {:status=>"success", :code=>200, :message=>"Hello", data: record_list}

Will returns this :

{
    "status": "success",
    "code": 200,
    "message": "Hello",
    "data": [
        {
            "id": 1,
            "raw": "aaa",
            "created_at": "2018-07-16T19:49:32.960Z",
            "updated_at": "2018-07-16T19:49:32.960Z",
        },
        {
            "id": 2,
            "raw": "bbb",
            "created_at": "2018-07-16T20:01:55.804Z",
            "updated_at": "2018-07-16T20:01:55.804Z",
        }
    ]
}

So I think I understand that render json: my_variable alone will understand to transform my_variable into the choosen json serializer adapter but cannot with a custom Hash ?

Of course I could do this :

record_list = {}
record_list["records"] = @current_user.records.select(:id, :raw)

But I feel like this is not the right way and then the Serializer would be useless.

Thanks !

ZazOufUmI
  • 3,212
  • 6
  • 37
  • 67
  • have you thought about opting out of serializers and using [jbuilder](https://github.com/rails/jbuilder) instead? – andrew21 Jul 17 '18 at 19:00
  • you might want to look into json:api and graphQL which both have gems that will set you up with generated serializers that work almost out of the box and provide a lot more structure and functionality than jsend – robertoplancarte Jul 17 '18 at 22:20
  • @robertoplancarte JSON API and graphQL seems heavy for my usage so this is why I wanted something light. – ZazOufUmI Jul 18 '18 at 09:10
  • @andrew21 I will look at it but this seems to bypass the issue and not really solve it. Thanks anyway for the suggestion – ZazOufUmI Jul 18 '18 at 09:12
  • For my Rails-based API application I initially started with [representable](https://github.com/trailblazer/representable) for generating JSON responses but as my JSON templates grown it didn't provided a clean approach to reuse already defined representations and thus I switched to used [rabl-rails](https://github.com/ccocchi/rabl-rails) and since then I am successfully and satisfactorily using it for generating JSON responses. (contd in next comment) – Jignesh Gohel Jul 18 '18 at 16:10
  • Next when Rails 5 was released [rails-api](https://github.com/rails-api/rails-api) gem was made part of [Rails](https://github.com/rails/rails/pull/19832). And I evaluated Rails API serializers but it didn't turned out to be the solution to replace 3rd party gems for JSON templating in my application. As part of that evaluation I also created a [SO post](https://stackoverflow.com/q/34001012/936494) reporting the problem I was facing but I didn't received any responses. Thus I decided to stick to rabl-rails and I am continuing using it without any issues and I would suggest you to try it too. – Jignesh Gohel Jul 18 '18 at 16:15
  • Thank you very much for sharing your experience @JiggneshhGohel If I don't find a "better" solution, I think I will consider going for rails-api even if it's overkill for my usage for now or for rabl-rails – ZazOufUmI Jul 18 '18 at 16:32

1 Answers1

2

I've chosen to give it a try to the Fast JSON API gem from the Netflix team. Great customisation possible, fast and lightweight.

ZazOufUmI
  • 3,212
  • 6
  • 37
  • 67