angelo icon indicating copy to clipboard operation
angelo copied to clipboard

Allow Additional Content Types

Open edpaget opened this issue 11 years ago • 7 comments

I was working on adding support for handling arbitrary content types in responses and wanted to run my idea by you to see if you'd want it included in Angelo.

As far as I can tell only content types explicitly handled here and here are allowed in request handlers.

I'd like to a method to Angelo::Base that allows you to declare new content types in the body of the App class like add_content_type(type_alias, mime_type, klass=nil, &block). It would let you declare a symbol alias to use in request handlers, the associated mime type for the response header, and a lambda or class (with a .call(body) instance method) to process the response body.

For example if json handling wasn't built in it could be declared like this

class App < Angelo::Base
  add_content_type :json, "application/json" do |body|
    case body
    when String
       JSON.parse(body) # for the raises
       body
     when Hash
       body.to_json
     end
  end

  get '/' do
    content_type :json
    { "this" => "becomes json" }
  end  
end

or with a class

class JSONResponseBody
  def call(body)
    case body
    when String
       JSON.parse(body) # for the raises
       body
     when Hash
       body.to_json
     end
  end
end

class App < Angelo::Base
  add_content_type :json, "application/json", JSONResponseBody

  get '/' do
    content_type :json
    { "this" => "becomes json" }
  end  
end

edpaget avatar Dec 01 '14 16:12 edpaget

@edpaget i like this idea! the content_type + response handling has always felt a bit clunky to me, this would be a good opportunity to tidy that up. thank you!

kenichi avatar Dec 02 '14 18:12 kenichi

Great I'll keep working on it then.

edpaget avatar Dec 02 '14 23:12 edpaget

@edpaget thanks, let me know if you have further questions; otherwise, i humbly await a PR.

kenichi avatar Dec 03 '14 03:12 kenichi

@edpaget getting close to a 0.4 release, tons of changes; wanted to check in on this status.

kenichi avatar Feb 05 '15 17:02 kenichi

Hi @kenichi, I'm very sorry I ended up being way busier at work than I thought I would be. I have a semi working implementation without any additional tests so far. I think I should have something for you by this weekend at the latest.

edpaget avatar Feb 06 '15 07:02 edpaget

I don't see how this is so difficult. I just solved it myself in a matter of minutes:

class AngeloServer < Angelo::Base
 def content_type type
  case type
   when :css
    headers 'Content-Type' => 'text/css'
   when Symbol
    super
   else
    headers 'Content-Type' => type
  end
 end
 def transfer_encoding encoding           # just because you ought to have this as well
  headers 'Transfer-Encoding' => encoding
 end
end

Usage:

get '/css/*.css' do
 content_type :css
 ...
end

Which reminds me: get and post blocks should be able to take parameters from the pattern, like in Sinatra. I've implemented that in my code as well, if you're interested.

stugol avatar Sep 11 '16 02:09 stugol

Yes, PRs are very welcome!

kenichi avatar Sep 24 '16 00:09 kenichi