Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 5 additions & 39 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,18 @@ jobs:
build:
strategy:
matrix:
ruby_version: ['3.0', '2.7', '2.6']

gemfile:
- gemfiles/rails_61.gemfile
- gemfiles/rails_60.gemfile

include:
- ruby_version: ruby-head
gemfile: gemfiles/rails_edge.gemfile
allow_failures: 'true'
- ruby_version: '3.0'
gemfile: gemfiles/rails_edge.gemfile
allow_failures: 'true'

- ruby_version: '2.7'
gemfile: gemfiles/rails_edge.gemfile
allow_failures: 'true'

- ruby_version: '2.6'
gemfile: gemfiles/rails_52.gemfile
- ruby_version: '2.6'
gemfile: gemfiles/rails_51.gemfile
- ruby_version: '2.6'
gemfile: gemfiles/rails_50.gemfile
- ruby_version: '2.6'
gemfile: gemfiles/rails_42.gemfile
bundler_version: '1'

- ruby_version: '2.5'
gemfile: gemfiles/rails_52.gemfile
- ruby_version: '2.5'
gemfile: gemfiles/rails_42.gemfile
bundler_version: '1'
ruby: ['3.2', '3.3', '3.4']
rails: ["7.1", "7.2", "8.0"]

runs-on: ubuntu-latest

env:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.rails }}.gemfile

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby_version }}
bundler: ${{ matrix.bundler_version }}
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
continue-on-error: ${{ matrix.allow_failures == 'true' }}
- run: bundle exec rake
continue-on-error: ${{ matrix.allow_failures == 'true' }}
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# SimpleJson

A simple & fast solution for Rails JSON rendering.

## Get started

In Gemfile

```ruby
gem 'simple_json'
```

In controller

```ruby
class ApplicationController < ActionController::Base
include SimpleJson::SimpleJsonRenderable
Expand Down Expand Up @@ -44,18 +48,23 @@ That's all!
Have fun!

## Special thanks

This project is built on work of [jb](https://github.com/amatsuda/jb).

## Template Syntax

SimpleJson templates are simply lambda objects that return data(Hashes or Arrays) for json.

```ruby
-> {
{
key: @value,
}
}
```

When no parameters specified, `-> {` and `}` can be omitted.

```ruby
{
key: @value,
Expand Down Expand Up @@ -83,62 +92,75 @@ Use `partial!` method to call another template in template. Note that path is al
```

Cache helpers of simple_json is similar to jbuilder.

```ruby
cache! key, options do
data_to_cache
end
```

Cache helpers uses `Rails.cache` to cache, so array keys, expirations are available. Make sure `perform_caching` is enabled.

```ruby
cache! [key1, key2], expires_in: 10.minutes do
data_to_cache
end
```

`cache_if!` is also available

```ruby
cache_if! boolean, key1, options do
data_to_cache
end
```

You can set key_prefix for caching like this

```ruby
SimpleJson.cache_key_prefix = "MY_PREFIX"
```

## Configurations

Load all templates on boot. (For production)
Templates loaded will not load again, so it is not recommended in development environment.

```ruby
# config/environments/production.rb
SimpleJson.enable_template_cache
```

The default path for templates is `app/views`, you can change it by

```ruby
SimpleJson.template_paths.append("app/simple_jsons")
# or
SimpleJson.template_paths=["app/views", "app/simple_jsons"]
```

Note that these paths should not be eager loaded cause using .rb as suffix.

SimpleJson uses Oj as json serializer by default. Modules with `#encode` and `#decode` method can be used here.

```ruby
SimpleJson.json_module = ActiveSupport::JSON
```

## The Generator

SimpleJson extends the default Rails scaffold generator and adds some simple_json templates. If you don't need them, please configure like so.

```rb
Rails.application.config.generators.simple_json false
```

## Benchmarks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's update these benchmark results.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, bin/benchmark.sh can not running in RAILS_ENV=production. I plan to fix this issue in a separate PR (and will be update bench result).


Here're the results of a benchmark (which you can find [here](https://github.com/aktsk/simple_json/blob/master/test/dummy_app/app/controllers/benchmarks_controller.rb) in this repo) rendering a collection to JSON.

### RAILS_ENV=development

```
% ./bin/benchmark.sh

Expand Down Expand Up @@ -189,7 +211,9 @@ Comparison:
jb: 106.1 i/s - 2.56x (± 0.00) slower
jbuilder: 13.0 i/s - 20.88x (± 0.00) slower
```

### RAILS_ENV=production

```
% RAILS_ENV=production ./bin/benchmark.sh

Expand Down Expand Up @@ -242,13 +266,16 @@ Comparison:
```

## Migrating from Jbuilder

When migrating from Jbuilder, you can include `Migratable` in controller for migrating mode.

```
include SimpleJson::SimpleJsonRenderable
include SimpleJson::Migratable
```

In migrating mode

- Comparision will be performed for simple_json and ActionView render(Jbuilder) result.
- simple_json partials not found will use Jbuilder partial as an alternative.

Expand Down
9 changes: 0 additions & 9 deletions gemfiles/rails_42.gemfile

This file was deleted.

8 changes: 0 additions & 8 deletions gemfiles/rails_50.gemfile

This file was deleted.

8 changes: 0 additions & 8 deletions gemfiles/rails_52.gemfile

This file was deleted.

2 changes: 1 addition & 1 deletion gemfiles/rails_60.gemfile → gemfiles/rails_7.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ source 'https://rubygems.org'
gemspec path: '../'

gem 'jbuilder'
gem 'rails', '~> 6.0.0'
gem 'rails', '~> 7.1.0'
gem 'selenium-webdriver'
2 changes: 1 addition & 1 deletion gemfiles/rails_61.gemfile → gemfiles/rails_7.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ source 'https://rubygems.org'
gemspec path: '../'

gem 'jbuilder'
gem 'rails', '~> 6.1.0'
gem 'rails', '~> 7.2.0'
gem 'selenium-webdriver'
3 changes: 2 additions & 1 deletion gemfiles/rails_51.gemfile → gemfiles/rails_8.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ source 'https://rubygems.org'
gemspec path: '../'

gem 'jbuilder'
gem 'rails', '~> 5.1.0'
gem 'rails', '~> 8.0.0'
gem 'selenium-webdriver'
7 changes: 4 additions & 3 deletions simple_json.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ Gem::Specification.new do |spec|

spec.add_development_dependency 'action_args'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'byebug'
spec.add_development_dependency 'rails'
spec.add_development_dependency 'debug'
spec.add_development_dependency 'rails', '~> 8.0'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'selenium-webdriver'
spec.add_development_dependency 'test-unit-rails'
spec.add_development_dependency 'mutex_m'

spec.required_ruby_version = '>= 2.5.0'
spec.required_ruby_version = '>= 3.2.0'
end
18 changes: 16 additions & 2 deletions test/dummy_app/app/controllers/benchmarks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,28 @@ def index(n = '100')

jb = render_to_string 'index_jb'
jbuilder = render_to_string 'index_jbuilder'
simple_json = render_to_string 'index_simple_json'

SimpleJson.json_module = SimpleJson::Json::Oj
simple_json = render_to_string 'index'

SimpleJson.json_module = ActiveSupport::JSON
simple_json_active_support_json = render_to_string 'index'

raise 'jb != jbuilder' unless jb == jbuilder
raise 'simple_json != jbuilder' unless simple_json == jbuilder
raise 'simple_json_active_support_json != jbuilder' unless simple_json_active_support_json == jbuilder

result = Benchmark.ips do |x|
x.report('jb') { render_to_string 'index_jb' }
x.report('jbuilder') { render_to_string 'index_jbuilder' }
x.report('simple_json') { render_to_string 'index_simple_json' }
x.report('simple_json(oj)') {
SimpleJson.json_module = SimpleJson::Json::Oj
render_to_string 'index'
}
x.report('simple_json(AS::json)') {
SimpleJson.json_module = ActiveSupport::JSON
render_to_string 'index'
}
x.compare!
end
render plain: result.data.to_s
Expand Down
7 changes: 7 additions & 0 deletions test/dummy_app/bin/bench.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

require 'action_dispatch/testing/integration'

puts 'SimpleJson Benchmark'
puts "ruby: #{RUBY_VERSION}"
puts "rails: #{Rails.version}"
puts "json: #{JSON::VERSION}"
puts "oj: #{Oj::VERSION}"
puts "----------------------"

puts '* Rendering 10 partials via render_partial'
ActionDispatch::Integration::Session.new(Rails.application).get '/benchmarks.json?n=10'

Expand Down
2 changes: 1 addition & 1 deletion test/dummy_app/config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
config.action_controller.perform_caching = false

# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
config.action_dispatch.show_exceptions = :none

# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

Bundler.require
require 'action_args'
require 'byebug'
require 'debug'
require 'test/unit/rails/test_help'