Active_model_serializers: Adding custom mime type for 'application/vnd.api+json' seems to be required to receive data from clients using JSON API

Created on 30 Jul 2015  Â·  18Comments  Â·  Source: rails-api/active_model_serializers

Using ember and ember-data with it's built in JSON API support means my client is sending POST/PUT/PATCH requests with ContentType set to 'application/vnd.api+json'.

By default, even though I've set my adapter in my rails app to:json_api, the controller action for create/update doesn't receive any data.

After some troubleshooting and googling, I've found out I need to create an initializer to set the rails application to interpret 'application/vnd.api+json' as json:

ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime::Type.lookup('application/vnd.api+json')]=lambda do |body|
  JSON.parse(body)
end

Once this was added, I'm receiving the data as expected.

The issue here is, i'm not sure if this is what I'm supposed to be doing.

  1. Will AMS at some point do this, or something similar internally?
  2. Should I do it this way?
  3. Should I do it some other, more proper way?
  4. Did I miss something altogether? Is it well documented already and I actually just didn't set some property somewhere?

If it's one of the first 3, I'm thinking it should be documented in some way.

Documentation JSON API Needs Bug Verification

Most helpful comment

hey @begedin I'm using rails with AMS .10 and the latest ember/ember-data (1.13). I added this as an initializer (e.g. config/initializers/register_json_api_mime_type.rb in your rails app):

api_mime_types = %W(
  application/vnd.api+json
  text/x-json
  application/json
)

Mime::Type.unregister :json
Mime::Type.register 'application/json', :json, api_mime_types

and everything seems to be working fine :).

All 18 comments

Hey @begedin, thank you for the issue:

1 - Will AMS at some point do this, or something similar internally?

Probably, you might not even need to set the adapter depending on how we decide to do this.

2 - Should I do it this way?

Not sure, we haven't started to implement it so it's a new problema for us as well, but we are already working on deserialization, what means we will face this problem soon.

3 - Should I do it some other, more proper way?

As I said, I'm not sure, we will face the same problem on the deserialization implementation the next days, so might find another way but you're ahead of us for now :smile:

4 - Did I miss something altogether? Is it well documented already and I actually just didn't set some property somewhere?

No, we don't support it yet.

I'll close this one for now but will keep the dicussion opened, mostly because I want to give updates base on the implementation that we will work on! Also, @begedin, let us know in case you have any problem with this, I might open the issue again and we will definitely help you :smile:

hey @begedin I'm using rails with AMS .10 and the latest ember/ember-data (1.13). I added this as an initializer (e.g. config/initializers/register_json_api_mime_type.rb in your rails app):

api_mime_types = %W(
  application/vnd.api+json
  text/x-json
  application/json
)

Mime::Type.unregister :json
Mime::Type.register 'application/json', :json, api_mime_types

and everything seems to be working fine :).

@shicholas That seems like a cleaner way to do it, so thank you for that snippet.

@shicholas Thanks, that was a great help.

@shicholas Thank you very much!

@joaomdmoura any news on when we won't have to declare custom MIME type manually for when json_api adapter is selected?

@matixmatix right now that change would have to be in the Rails JSON Renderer, if I'm not mistaken. or do you mean something like https://github.com/rails-api/active_model_serializers/issues/1027#issuecomment-126543577

Thank you @rashkov.

Mime::Type.unregister :json
Mime::Type.register "application/json", :json, %w( text/x-json application/json application/vnd.api+json )
ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime::Type.lookup('application/vnd.api+json')]=lambda do |body|
JSON.parse(body)
end

This solved my issue.

@boobooninja this solution is technically incorrect, even though it works fine.

I basically just removed this pattern from Rails 5.

Better would be to register a jsonapi renderer

@bf4 could you elaborate ? Could you give a dirty but correct solution ?

I use 0.10.0.rc5 with JSONAPI and I had the same issue. It can be VERY furstrating I thing I am lucky that I found this issue in the first 30 mins. What it needs to be done so that users don't have this issue ?

ActiveSupport.on_load :action_controller do
require 'active_model_serializers/register_jsonapi_some.....
End

Sorry, on phone

If you can make a pr summarizing what brought you here and what the solution is, that would be great.

Maybe see http://www.benjaminfleischer.com/journey-of-a-media-type-in-rails-part-1 re content negotiation

B mobile phone

On May 20, 2016, at 3:19 PM, Filippos Vasilakis [email protected] wrote:

@bf4 could you elaborate ? Could you give a dirty solution ?

I use 0.10.0.rc5 with JSONAPI and I had the same issue. It can be VERY furstrating I thing I am lucky that I found this issue in the first 30 mins. What it needs to be done so that users don't have this issue ?

—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

I am using AMS 0.10.2 with Ember 2.7 and did not need to register a mime type for everything to work. I simply added the AMS gem and configured it as recommended:

/config/initializers/active_model_serializer.rb

require 'active_model_serializers/register_jsonapi_renderer'

ActiveModelSerializers.config.adapter = :json_api

However, the Header being sent from Rails is application/json and not application/vnd.api+json

My understanding is that if you want the api to be spec-compliant, the server should respond with the latter mime-type.

In order to achieve that, then you need to register the correct mime-type, even though it seems Ember and the API work without doing so.

api_mime_types = %W(
  application/vnd.api+json
  text/x-json
  application/json
)
Mime::Type.register 'application/vnd.api+json', :json, api_mime_types

Is there some mismatch going on here or am I just not groking something here?
It seems strange to have to need two initialisers.

@rmcsharry are you using format.jsonapi or render :jsonapi? I believe that will give you the correct response header without the additional initializer. See https://github.com/rails-api/active_model_serializers/blob/master/docs/integrations/ember-and-json-api.md.

You shouldn't need to register the mime type yourself anymore, if you are using require 'active_model_serializers/register_jsonapi_renderer'. The code does that for you and this line should render the correct header.

If that helps, I suggest we close this issue (as much of the discussion is dated and now misleading) and maybe make that section of the documentation more obvious.

I think I'm having this exact issue. I'm using AMS 0.10.4 with Rails 4.2.

Testing in postman, it only seems to accept application/json. When Content-Type is application/vnd.api+json, it throws the error stated above:
screen shot 2017-01-20 at 6 33 54 pm

Is there something obvious I'm missing? Maybe there's another gem that's interfering. I did include the special initializer mentioned in the ember README.

EDIT:
Fixed it, I had the include, but I was missing inheriting from ActionController::API.

@allthesignals I have a PR open in Rails to return a 415 when a mime type isn't registered. There's a lot of misinformation on the web. Register vnd.api+json as its own media type. AMS provides a way to do this for you.

To enable the mime type application/vnd.api+json in the gem version >= v0.10.1, do this:

Add this to your controller:
require 'active_model_serializers/register_jsonapi_renderer'

And use the type json_api in your render:

def show
  resource = Resource.find(params[:id])
  render jsonapi: resource
end

And then in the response, you'll see the header content-type with application/vnd.api+json

References:
https://github.com/rails-api/active_model_serializers/pull/1747 - Improve jsonapi mime type registration for Rails 5 (@remear)
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/mime_types.rb
http://www.seanbehan.com/how-to-get-a-list-of-all-registered-mime-types-in-rails/

hey @begedin I'm using rails with AMS .10 and the latest ember/ember-data (1.13). I added this as an initializer (e.g. config/initializers/register_json_api_mime_type.rb in your rails app):

api_mime_types = %W(
  application/vnd.api+json
  text/x-json
  application/json
)

Mime::Type.unregister :json
Mime::Type.register 'application/json', :json, api_mime_types

and everything seems to be working fine :).

This solved for me. Thank you!

@jramiresbrito I'm glad that worked for you. Please be aware we do not recommend that and provide a solution. In the future, when commenting on (years) old resolved threads, it is a good practice to include in your comment what new information you are adding which justifies the thread necromancy. I'm locking this thread now since there's ample references in it to justify it being closed, IMHO.

Was this page helpful?
0 / 5 - 0 ratings