Grape: Override content type

Created on 26 May 2013  路  17Comments  路  Source: ruby-grape/grape

In a project I'm working on we are having some issues with a recent change (#347). We have a JSON API that has some calls that return RAW content (raw blobs of code). Prior to #347, this was no problem. But now, it puts the entire content in quotes and all new lines are encoded as \n.

Is there a way to override the content type for certain APIs so that this type of content is delivered in plain text? Thanks.

Most helpful comment

I looked at your code. Here's my diff:

Gemfile

gem "grape", :git => "https://github.com/intridea/grape.git"

api.rb

    format :json
    content_type :txt, 'text/plain'

    get 'foo' do
      content_type 'text/plain'
      "hello world"
    end

spec/requests/api/foo_spec.rb

require 'spec_helper'

describe API::API do
  include ApiHelpers

  it "foo" do
    get api("/foo")
    response.body.should == "hello world"
  end
end

This works. What do you have?

All 17 comments

Might want to bring up things like this on the list.

I think all you need to do is set content type with content_type "text/plain" when returning raw text or content_type "application/octet-stream" for random binary content. Make sure any such content type is also declared, eg. content_type :binary, "application/octet-stream".

Reopen with a repro if this is still an issue.

+1. Adding content_type "text/plain" does not help me. Looks like it still got to_json before render

Confirming it's a bug.

@dblock thank you

Fixed in https://github.com/intridea/grape/commit/dce96e180878ae11893c8c7982ec5abcc2811454, please let me know if that works. There's a workaround for existing versions, do env['api.format'] = :txt inside the API.

@dblock thank you a lot. env['api.format'] = :txt works great.
But pointing to dce96e180878ae11893c8c7982ec5abcc2811454 doesnt work for me.

Anyway thank you because I applied env['api.format'] = :txt https://github.com/gitlabhq/gitlabhq/commit/9351a295c1ac84e2e67559a9140cb921445c8951#L2R127 and everything is ok now :)

I want to make sure this does work when the next version is released. Double-check that you're pointing to Grape HEAD.

I added a demo to my little rack app, https://github.com/dblock/grape-on-rack/commit/39a166e2d84037b8c905a83dfe07bba696fe325f and it worked OK.

You can monkey patch the formatter to see what's going on.

module Grape
  module Middleware
    class Formatter < Base
      def after
        status, headers, bodies = *@app_response
        puts "headers: #{headers}"
        puts "content type: #{headers['Content-Type']}"
        puts "mime type: #{mime_types[headers['Content-Type']]}"
        puts "api format: #{env['api.format']}"
        raise "stop here"      
      end
    end
  end
end

The above should have the correct mime type, :txt for text.

I want to make sure this does work when the next version is released. Double-check that you're pointing to Grape HEAD.

done

You can monkey patch the formatter to see what's going on.

Thanks. I'll do

HEAD

Started GET "/api/v3/projects/15/repository/commits/72d5a566b46db918b17a1040b6e6d0a3dd986386/blob?filepath=Gemfile.lock"

headers: {"Content-Type"=>"text/plain"}
content type: text/plain
mime type: 
api format: json
RuntimeError (stop here):

HEAD + env['api.format'] = :txt

Started GET "/api/v3/projects/15/repository/commits/72d5a566b46db918b17a1040b6e6d0a3dd986386/blob?filepath=Gemfile.lock"

headers: {"Content-Type"=>"text/plain"}
content type: text/plain
mime type: 
api format: txt

Do you have a content_type :txt, 'text/plain' declared for the API itself? When you do format :json that removes all default known content types and formatters.

nope. Added. See output:

HEAD + content_type :text, 'text/plain' inside API class

headers: {"Content-Type"=>"text/plain"}
content type: text/plain
mime type: text
api format: json

Sorry, change :text to :txt. It doesn't have a formatter for :text.

HEAD + content_type :txt, 'text/plain' inside API class

headers: {"Content-Type"=>"text/plain"}
content type: text/plain
mime type: txt
api format: json

I looked at your code. Here's my diff:

Gemfile

gem "grape", :git => "https://github.com/intridea/grape.git"

api.rb

    format :json
    content_type :txt, 'text/plain'

    get 'foo' do
      content_type 'text/plain'
      "hello world"
    end

spec/requests/api/foo_spec.rb

require 'spec_helper'

describe API::API do
  include ApiHelpers

  it "foo" do
    get api("/foo")
    response.body.should == "hello world"
  end
end

This works. What do you have?

Ok I can confirm it works now. Thank you very much! I owe you a :beer: :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stabenfeldt picture stabenfeldt  路  6Comments

nab0310 picture nab0310  路  4Comments

TangMonk picture TangMonk  路  8Comments

jellybob picture jellybob  路  4Comments

dblock picture dblock  路  6Comments