Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Grape 0.4.0 escaping in responses? #371

Closed
mhenrixon opened this Issue Mar 20, 2013 · 6 comments

Comments

Projects
None yet
4 participants

This is what the API returns in the response body now.

["\"{\\\"color\\\":\\\"#14426a\\\",\\\"completed_percentage\\\":0,\\\"description\\\":\\\"MyText\\\",\\\"icon\\\":\\\"A\\\",\\\"id\\\":1,\\\"tags\\\":[],\\\"tasks_count\\\":0,\\\"title\\\":\\\"MyString\\\"}\""]

What would have changed from 0.3.2 to cause this? I can't parse this as json.

If I try with Yajl::Parser I get the following:

Yajl::Parser.parse(Yajl::Parser.parse(response.body)) =>  { "color"=>"#14426a",
 "completed_percentage"=>0,
 "description"=>"MyText",
 "icon"=>"A",
 "id"=>1,
 "tags"=>[],
 "tasks_count"=>0,
 "title"=>"MyString"}

No idea what is up with that but any suggestions on how to fix it would be deeply appreciated.

Contributor

qqshfox commented Mar 21, 2013

quick response, maybe related to 6fa8f59.

Would you mind providing a spec or something like that?

We had the same issue, downgrading to 0.3.2 fixed this for us

# lib/api/articles.rb

require 'grape'

module API
  class Articles < ::Grape::API
    use Rack::Session::Cookie
    version 'v1', using: :path
    format :json

    resource :articles do
      get '/' do
        Article.all.to_json
      end
    end
  end
end
# spec/requests/api_spec.rb

require 'spec_helper'
require 'api/articles'

module API
  describe Articles do
    let(:article) { Article.new(title: 'HEY HO!!') }
    describe "GET /api/v1/articles" do
      it "returns an empty array of statuses" do
        article.save!
        get "/api/v1/articles"
        response.status.should == 200
        JSON.parse(response.body).should == []
      end
    end
  end
end

In case that isn't enough, here is a repo for you: https://github.com/mhenrixon/grape-serialization-bug

Contributor

qqshfox commented Mar 22, 2013

I think you dont need to call to_json explicitly. Grape will encode the return value from the block properly following the format what you indicated.

The 0.4 version changes what the api returns when the return value is a string.

JSON format APIs will always return valid JSON, eg. strings are now returned as "string" and no longer string

to_json returns a string which is also a valid json object, and the json encoder encode the string object to a valid json "string". I believe why you had to parse the response for twice.

Simply changing Article.all.to_json to Article.all.to_a will fix your spec.

Thanks,
Hanfei

PS. I think your spec will never pass... You saved a new article, then expected nothing in articles!

      it "returns an empty array of statuses" do
        article.save!
        get "/api/v1/articles"
        response.status.should == 200
        JSON.parse(response.body).should == []
      end

@qqshfox since any failure would show you whats up I just let it fail against empty array. Less code to write :)

Thanks for the pointers, glad to see it going in that direction. Really liked it when rails did that so I appreciate it.

Owner

dblock commented Mar 22, 2013

This is by design. I described exactly this problem in http://code.dblock.org/grape-040-released-w-stricter-json-format-support-more. If you're going to do to_json, you're returning a string, which itself needs to be encoded for JSON.

You can either monkey-patch things or return as_json.

@dblock dblock closed this Mar 22, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment