PerlerのRuby日記

Rubyとか

SinatraでJSONを返す

Sinatraと小さいAPIはとても相性がいい。

APIで返すものといえばJSONが最近は楽ですね。

まあ普通にrequire "json"して、#to_jsonすればよいのですが、

sinatra-contribにあるsinatra/jsonを使うのもよいかと思います。

Sinatraだけの場合

app.rb
require "sinatra"
require "json"

get '/' do
  content_type :json
  data = { foo: "bar" }
  data.to_json
end

Sinatra::JSONを使う場合

Gemfile
gem "sinatra"
gem "sinatra-contrib"
app.rb
require "sinatra"
require "sinatra/json"

get '/' do
  data = { foo: "bar" }
  json data
end

こんな感じ。

json_encoderオプション

json_encoderというオプションをjsonメソッドで渡すか、set :json_encoderで設定すればそのメソッドで最後仕上げてくれる。

# setで全体的な設定をする
set :json_encoder, :foooooooo

get '/' do
  data = { foo: "bar" }
  def data.foooooooo
    '{"hoge":"fuga"}'
  end
  # あるいは実行時に渡す(優先度はこっちが上)
  json data, :json_encoder => :foooooooo
end

json_content_typeオプション

これもjson_encoderと同じ形。APIで使うならデフォルトのまま

Content-Type: application/json;charset=utf-8

か、JSで使うように

# setで全体的な設定をする
set :json_content_type, :js

get '/' do
  data = { foo: "bar" }
  # あるいは実行時に渡す(優先度はこっちが上)
  json data, :content_type => :js
  #=> Content-Type: application/javascript;charset=utf-8
end

くらいがJSONP的な使いどころとして思いつくくらいでしょうか。


ドキュメントとちょっと違ってた

1

ドキュメントにはto_jsonのcallを試みると書いてあるけど、

特にそんなそぶりはない。

get '/' do
  data = { foo: "bar" }
  def data.to_json
    '{"hoge":"fuga"}'
  end
  json data
  #=> {"foo":"bar"}
end

実装も、デフォルトでは、MultiJSON#encodeが呼ばれて終わりだった。

小さいけど

content_typeのオーバーライドで

get '/' do
  json({:foo => 'bar'}, :encoder => :to_json, :content_type => :js)
end

とあったけど:encoderは:json_encoderの誤りだと思う。


ちょっと調べてからぷるりくしてみたい。


公式サイト

Sinatra::JSON (part of Sinatra::Contrib)