Allow Additional Content Types
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 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!
Great I'll keep working on it then.
@edpaget thanks, let me know if you have further questions; otherwise, i humbly await a PR.
@edpaget getting close to a 0.4 release, tons of changes; wanted to check in on this status.
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.
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.
Yes, PRs are very welcome!