Rails-api has been merged into normal rails, but this is what I’m working with. I’m fairly certain the process will be identical for someone using the new setup!
I wanted to build an API whose responses had a reusable wrapper, just like an HTML response can be wrapped in a reusable header and footer. The process to do this is easy, but not totally neat, for reasons I’ll get into.
Anyways, here’s what you need.
# app/controllers/application_controller.rb class ApplicationController < ActionController::API include ActionController::ImplicitRender include ActionView::Layouts end
# app/views/application.json.jbuilder json.head("This will appear in every response") json.body(JSON.parse(yield))
JSON.parse(yield) stands in for the normal yield you are used to when rendering HTML with erb or what have you.
This code is not ideal because the use of
JSON.parse(yield) means that the body of your JSON response is parsed twice. It is hella inefficient.
I’ve done a fair amount of research, and it seems this is simply a limitation of JBuilder. This Github conversation confirms this. If anyone hears of a good solution or workaround, please let me know! And I think ActiveModel::Serializer is not the way for me, but I would love to be convinced!
I suppose you don’t even need to
include ActionController::ImplicitRender but it has made my life a whole lot easier! It means you don’t have to specify which jbuilder file to load at the end of a controller; Rails will try to figure out which one based on naming conventions as it does with normal erb views. If your goal is to try and get rails-api to behave like Rails but with JSON instead of HTML, then you need ImplicitRender.