diff --git a/README.md b/README.md index c046b73..76183d9 100644 --- a/README.md +++ b/README.md @@ -30,16 +30,13 @@ PersonSerializer.new(person).to_json #=> '{"name":"John Doe",...}' ## JSON serialization Granola doesn't make assumptions about your code, so it shouldn't depend on a -specific JSON backend. It uses [MultiJson][] to serialize your objects with your -favorite backend. +specific JSON backend. It defaults to the native JSON backend, but you're free +to change it. For example, if you were using [Yajl][]: -Try to avoid using the default, which is the `stdlib`'s pure-ruby JSON library, -since it's slow. If in doubt, I like [Yajl][]. - -If you want to pass options to `MultiJson` (like `pretty: true`), any keywords -passed to `#to_json` will be forwarded to `MultiJson.dump`. +``` ruby +Granola.json = ->(obj, **opts) { Yajl::Encoder.encode(obj, opts) } +``` -[MultiJson]: https://github.com/intridea/multi_json [Yajl]: https://github.com/brianmario/yajl-ruby ## Handling lists of models diff --git a/granola.gemspec b/granola.gemspec index 0fd000d..5929340 100644 --- a/granola.gemspec +++ b/granola.gemspec @@ -20,9 +20,7 @@ Gem::Specification.new do |s| "lib/granola/caching.rb", ] - s.add_dependency "multi_json", "~> 1.10" - s.add_development_dependency "cutest", "~> 1.2" - s.add_development_dependency "rack", "~> 1.5" + s.add_development_dependency "rack", "~> 2.5" end diff --git a/lib/granola.rb b/lib/granola.rb index 5b023d2..25191e3 100644 --- a/lib/granola.rb +++ b/lib/granola.rb @@ -1,7 +1,23 @@ -require "multi_json" require "granola/version" +require "json" module Granola + class << self + # Public: Get/Set a Proc that takes an Object and a Hash of options and + # returns a JSON String. + # + # The default implementation uses the standard library's JSON module, but + # you're welcome to swap it out. + # + # Example: + # + # require "yajl" + # Granola.json = ->(obj, **opts) { Yajl::Encoder.encode(obj, opts) } + attr_accessor :json + end + + self.json = ->(obj, **opts) { JSON.dump(obj) } + # A Serializer describes how to serialize a certain type of object, by # declaring the structure of JSON objects. class Serializer @@ -35,13 +51,13 @@ def attributes fail NotImplementedError end - # Public: Generate the JSON string using the current MultiJson adapter. + # Public: Generate the JSON String. # - # **options - Any options valid for `MultiJson.dump`. + # **options - Any options to be passed to the `Granola.json` Proc. # # Returns a String. def to_json(**options) - MultiJson.dump(attributes, options) + Granola.json.(attributes, options) end # Public: Returns the MIME type generated by this serializer. By default diff --git a/test/serialize_test.rb b/test/serialize_test.rb index e0ff4df..e42e84d 100644 --- a/test/serialize_test.rb +++ b/test/serialize_test.rb @@ -50,3 +50,14 @@ def mime_type assert_equal %q|[{"a":1,"b":2},{"a":3,"b":4}]|, serializer.to_json end end + +scope do + prepare do + Granola.json = ->(obj, **opts) { "success!" } + end + + test "serializes with a custom json backend" do + serializer = OpenStructSerializer.new(OpenStruct.new) + assert_equal "success!", serializer.to_json + end +end