18

I am trying to use Ruby on Rails to communicate with the Salesforce API. I can fetch data easily enough but I am having problems posting data to the server. I am using HTTParty as per Quinton Wall's post here:

https://github.com/quintonwall/omniauth-rails3-forcedotcom/wiki/Build-Mobile-Apps-in-the-Cloud-with-Omniauth,-Httparty-and-Force.com

but all I seem to be able to get from the salesforce server is the error that I am submitting the body as html

{"message"=>"MediaType of 'application/x-www-form-urlencoded' is not supported by this resource", "errorCode"=>"UNSUPPORTED_MEDIA_TYPE"}

the responsible code looks like:

require 'rubygems'
require 'httparty'

class Accounts
  include HTTParty
  format :json

  ...[set headers and root_url etc]

  def self.save
    Accounts.set_headers
    response = (post(Accounts.root_url+"/sobjects/Account/", :body => {:name => "graham"}.to_json))
  end
end

anyone have an idea why the body should be being posted as html and how to change this so that it definitely goes as json so that salesforce doesn't reject it?

Any help would be appreciated. cheers

Paweł Gościcki
  • 9,066
  • 5
  • 70
  • 81
GrahamJRoy
  • 1,603
  • 5
  • 26
  • 56

2 Answers2

22

The Content-Type header needs to be set to "application/json". This can be done by inserting :headers => {'Content-Type' => 'application/json'} as a parameter to post, ie:

response = post(Accounts.root_url+"/sobjects/Account/", 
  :body => {:name => "graham"}.to_json,
  :headers => {'Content-Type' => 'application/json'} )
jesse
  • 229
  • 2
  • 3
  • 1
    You may also wish to consider using the "application/vnd.api+json" mime type, [registered with IANA](http://www.iana.org/assignments/media-types/application/vnd.api+json) and documented as part of [jsonapi](http://jsonapi.org/) – jesse Jan 01 '14 at 11:50
15

You have to set the Content-Type header to application/json. I haven't used HTTParty, but it looks like you have to do something like

response = (post(Accounts.root_url+"/sobjects/Account/", :body => {:name => "graham"}.to_json) , :options => { :headers => { 'Content-Type' => 'application/json' } } )

I'm somewhat surpised that the format option doesn't do this automatically.

Jaco Pretorius
  • 24,380
  • 11
  • 62
  • 94
superfell
  • 18,780
  • 4
  • 59
  • 81
  • 1
    cheers. I've found that if I simply add the line headers 'Content-Type' => "application/json" above the request then this seems to do the trick as well. It must just default to html even though the body is set as json. thanks for your help – GrahamJRoy May 27 '11 at 17:08
  • is it possible that the to_json call is confusing it about the format of the body ? the other examples i saw didn't do that. – superfell May 27 '11 at 17:11
  • interesting. I get a json parse error if I leave it off: {"message"=>"Unrecognized token 'naegaa': was expecting 'null', 'true' or 'false' at [line:1, column:23]", "errorCode"=>"JSON_PARSER_ERROR"} – GrahamJRoy May 27 '11 at 17:49
  • weird how in the log it says that the Content-Type is sent, but the body is different if you put that manually in the headers, weird, sounds like a bug to me – Joe Cabezas Sep 27 '19 at 20:48