• This repository has been archived on 30/Jan/2019
  • Stars
    star
    244
  • Rank 165,885 (Top 4 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 14 years ago
  • Updated about 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rails provides an excellent XML Builder by default to build RSS and ATOM feeds, but nothing to help you build complex and custom JSON data structures. JSON Builder is here to help.

No longer maintained, please check out jbuilder

JSON Builder Build Status

Rails provides an excellent XML Builder by default to build RSS and ATOM feeds, but nothing to help you build complex and custom JSON data structures. The standard to_json works just fine, but can get very verbose when you need full control of what is generated and performance is a factor. JSON Builder hopes to solve that problem.

Sample Usage

require 'json_builder'

json = JSONBuilder::Compiler.generate do
  name 'Garrett Bjerkhoel'
  email '[email protected]'
  url user_url(user)
  address do
    street '1234 1st Ave'
    city 'New York'
    state 'NY'
    zip 10065
  end
  key :nil, 'testing a custom key name'
  skills do
    ruby true
    asp false
  end
  longstring do
    # Could be a highly intensive process that only returns a string
    '12345' * 25
  end
end

Which will generate:

{
  "name": "Garrett Bjerkhoel",
  "email": "[email protected]",
  "url": "http://examplesite.com/dewski",
  "address": {
    "street": "1234 1st Ave",
    "city": "New York",
    "state": "NY",
    "zip": 10065
  },
  "nil": "testing a custom key name",
  "skills": {
    "ruby": true,
    "asp": false
  },
  "longstring": "1234512345123451234512345..."
}

If you'd like to just generate an array:

array ['Garrett Bjerkhoel', 'John Doe'] do |name|
  first, last = name.split(' ')
  first first
  last last
end

Which will output the following:

[
  {
    "first": "Garrett",
    "last": "Bjerkhoel"
  },
  {
    "first": "John",
    "last": "Doe"
  }
]

Just a note, if you use an array block, all other builder methods will be ignored.

Using JSON Builder with Rails

First, make sure to add the gem to your Gemfile.

gem 'json_builder'

Second, make sure your controller responds to json:

class UsersController < ApplicationController
  respond_to :json
  
  def index
    @users = User.order('id DESC').page(params[:page]).per(2)
    respond_with @users
  end
end

Lastly, create app/views/users/index.json.json_builder which could look something like:

count @users.count
page @users.current_page
per_page @users.per_page
pages_count @users.num_pages
results @users do |user|
  id user.id
  name user.name
  body user.body
  url user_url(user)
  links user.links do |link|
    url link.url
    visits link.visits
    last_visited link.last_visited
  end
end

You will get something like:

{
  "count": 10,
  "page": 1,
  "per_page": 2,
  "pages_count": 5,
  "results": [
    {
      "id": 1,
      "name": "Garrett Bjerkhoel",
      "body": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod.",
      "url": "http://example.com/users/garrett-bjerkhoel",
      "links": [
        {
          "url": "http://github.com/",
          "visits": 500,
          "last_visited": "2011-11-271T00:00:01Z"
        },
        {
          "url": "http://garrettbjerkhoel.com/",
          "visits": 1500,
          "last_visited": "2011-11-261T00:00:01Z"
        }
      ]
    }, {
      "id": 2,
      "name": "John Doe",
      "body": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod.",
      "url": "http://example.com/users/john-doe",
      "links": [
        {
          "url": "http://google.com/",
          "visits": 11000,
          "last_visited": "2010-05-221T00:00:01Z"
        },
        {
          "url": "http://twitter.com/",
          "visits": 155012857,
          "last_visited": "2011-11-261T00:00:01Z"
        }
      ]
    }
  ]
}

Including JSONP callbacks

Out of the box JSON Builder supports JSONP callbacks when used within a Rails project just by using the callback parameter. For instance, if you requested /users.json?callback=myjscallback, you'll get a callback wrapping the response:

myjscallback([
  {
    "name": "Garrett Bjerkhoel"
  },
  {
    "name": "John Doe"
  }
])

To turn off JSONP callbacks globally or just per-environment:

Globally

ActionView::Base.json_callback = false

Per Environment

Sample::Application.configure do
  config.action_view.json_callback = false
end

Pretty Print Output

Out of the box JSON Builder supports pretty printing only during development, it's disabled by default in other environments for performance. If you'd like to enable or disable pretty printing you can do it within your environment file or you can do it globally.

With pretty print on:

{
  "name": "Garrett Bjerkhoel",
  "email": "[email protected]"
}

Without:

{"name": "Garrett Bjerkhoel", "email": "[email protected]"}

Per Environment

Sample::Application.configure do
  config.action_view.pretty_print_json = false
end

Globally

ActionView::Base.pretty_print_json = false

Speed

JSON Builder is very fast, it's roughly 3.6 times faster than the core XML Builder based on the speed benchmark.

             user       system      total       real
JSONBuilder  2.950000   0.010000    2.960000    (2.968790)
    Builder  10.820000  0.040000    10.860000   (10.930497)

Alternative libraries

There are alternatives to JSON Builder, each good in their own way with different API's and design approaches that are worth checking out. Although, I would love to hear why JSON Builder didn't fit your needs, by [message or issue.

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright Β© 2012 Garrett Bjerkhoel. See MIT-LICENSE for details.

More Repositories

1

kss-rails

A rails engine for @kneath's KSS documentation
JavaScript
152
star
2

itunes

A Ruby wrapper around the iTunes API that lets you search for any sort of data that is available on the iTunes store.
Ruby
122
star
3

cmd-enter

Every textarea should let you submit comments by pressing cmd-enter or ctrl-enter. For every site that doesn't support it, a kitten weeps. Here's to making less kittens weep.
JavaScript
36
star
4

wink

A Ruby wrapper for the Wink Hub API.
Ruby
18
star
5

mail_gate

Ruby
11
star
6

unifi

Collect your Unifi client data every 15 seconds and send it to an InfluxDB instance.
Go
10
star
7

wink-alfred

Alfred workflow for interacting with your Wink Hub
Ruby
4
star
8

serviced

An interface to dealing with the common pain points while dealing with 3rd parties APIs
Ruby
3
star
9

graphql-cursor

Add GraphQL Relay Cursor Pagination with Postgres.
Go
3
star
10

droplet

Droplet is a fully customizable dropdown plugin for jQuery.
JavaScript
3
star
11

html-pipeline-bitly

A HTML Pipeline filter for extracting URLs and making them bit.ly links.
Ruby
2
star
12

tesla_exporter

Go
2
star
13

open-rails-partial-vscode-extension

VS Code extension that supports opening Rails partials found in development from the browser.
TypeScript
2
star
14

dotpath

dotpath gives you utilities to navigate and modify hashes and arrays in Ruby with the JSON path to each value in the hash or array.
Ruby
1
star
15

awair_exporter

Go
1
star
16

garrettb-python

My website in django
Python
1
star
17

garrettb

Personal site
JavaScript
1
star
18

pngdiff

Go tool that will diff images on the fly
Go
1
star
19

textmate-bundle

My TextMate bundle
1
star
20

screenshots

AWS Lambda nodejs functions to generate screenshots and to also compare them.
JavaScript
1
star
21

clientend-python

Python
1
star
22

pagerduty-schedule-cop

Ruby
1
star
23

open-rails-partial-chrome-extension

Chrome extension that supports opening Rails partials found on the page in VS Code
TypeScript
1
star
24

glimpse

1
star
25

pubattlegrounds

Ruby
1
star