Class: Grape::Middleware::Formatter

Inherits:
Base
  • Object
show all
Defined in:
lib/grape/middleware/formatter.rb

Constant Summary collapse

CONTENT_TYPES =
{
  :xml => 'application/xml',
  :json => 'application/json',
  :atom => 'application/atom+xml',
  :rss => 'application/rss+xml',
  :txt => 'text/plain'
}
FORMATTERS =
{
  :json => :encode_json,
  :txt => :encode_txt,
}

Instance Attribute Summary

Attributes inherited from Base

#app, #env, #options

Instance Method Summary collapse

Methods inherited from Base

#call, #call!, #initialize, #request, #response

Constructor Details

This class inherits a constructor from Grape::Middleware::Base

Instance Method Details

#afterObject



85
86
87
88
89
90
91
92
93
# File 'lib/grape/middleware/formatter.rb', line 85

def after
  status, headers, bodies = *@app_response
  formatter = formatter_for env['api.format']
  bodymap = bodies.collect do |body|
    formatter.call(body)
  end
  headers['Content-Type'] = content_types[env['api.format']]
  Rack::Response.new(bodymap, status, headers).to_a
end

#beforeObject



43
44
45
46
47
48
49
50
51
# File 'lib/grape/middleware/formatter.rb', line 43

def before
  fmt = format_from_extension || format_from_header || options[:default_format]
          
  if content_types.key?(fmt)
    env['api.format'] = fmt          
  else
    throw :error, :status => 406, :message => 'The requested format is not supported.'
  end
end

#content_typesObject



27
28
29
# File 'lib/grape/middleware/formatter.rb', line 27

def content_types
  CONTENT_TYPES.merge(options[:content_types])
end

#default_optionsObject



19
20
21
22
23
24
25
# File 'lib/grape/middleware/formatter.rb', line 19

def default_options
  { 
    :default_format => :txt,
    :formatters => {},
    :content_types => {}
  }
end

#encode_json(object) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/grape/middleware/formatter.rb', line 107

def encode_json(object)
  if object.respond_to? :serializable_hash
    MultiJson.encode(object.serializable_hash)
  elsif object.respond_to? :to_json
    object.to_json
  else
    MultiJson.encode(object)
  end
end

#encode_txt(object) ⇒ Object



117
118
119
# File 'lib/grape/middleware/formatter.rb', line 117

def encode_txt(object)
  object.respond_to?(:to_txt) ? object.to_txt : object.to_s
end

#format_from_extensionObject



53
54
55
56
57
58
59
60
61
62
# File 'lib/grape/middleware/formatter.rb', line 53

def format_from_extension
  parts = request.path.split('.')
  hit = parts.last.to_sym
  
  if parts.size <= 1
    nil
  else
    hit
  end
end

#format_from_headerObject



64
65
66
67
68
69
70
71
# File 'lib/grape/middleware/formatter.rb', line 64

def format_from_header
  mime_array.each do |t| 
    if mime_types.key?(t)
      return mime_types[t]
    end
  end
  nil
end

#formatter_for(api_format) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/grape/middleware/formatter.rb', line 95

def formatter_for(api_format)
  spec = formatters[api_format]
  case spec
  when nil
    lambda { |obj| obj }
  when Symbol
    method(spec)
  else
    spec
  end
end

#formattersObject



31
32
33
# File 'lib/grape/middleware/formatter.rb', line 31

def formatters
  FORMATTERS.merge(options[:formatters])
end

#headersObject



39
40
41
# File 'lib/grape/middleware/formatter.rb', line 39

def headers
  env.dup.inject({}){|h,(k,v)| h[k.downcase] = v; h}
end

#mime_arrayObject



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/grape/middleware/formatter.rb', line 73

def mime_array
  accept = headers['accept']
  if accept
    accept.gsub(/\b/,'').
      scan(/(\w+\/[\w+]+)(?:;[^,]*q=([0-9.]+)[^,]*)?/i).
      sort_by{|a| -a[1].to_f}.
      map{|a| a[0]}
  else
    []
  end
end

#mime_typesObject



35
36
37
# File 'lib/grape/middleware/formatter.rb', line 35

def mime_types
  content_types.invert
end