Donatello

Donatello is a Ruby gem for effortlessly applying YAML-defined serialization schemas to Ruby objects, utilizing the speed of the Oj gem for optimal JSON output.

After spending a lot of time with GraphQL, when I started working with other types of JSON APIs, I missed being able to define my schema centrally.

Installation

Add this line to your application's Gemfile:

gem 'donatello'

And then execute:

$ bundle install

Or install it yourself with:

$ gem install donatello

Usage

Defining a Schema

Create a YAML file in your Rails project (e.g., config/serialization_schema.yml) that defines your serialization schema:

# Mixed-in field set serializers (similar concept to fragments in GraphQL)
common_fields:
  - id
  - created_at
  - updated_at

engagement:
  - likes_count
  - comments_count

# User-related serializers

public_user:
  - with: common_fields # use a single mixin
  - first_name
  - last_name

private_user:
  - with: public_user
  - access_token
  - email

author:
  - first_name
  - middle_initial
  - last_name
  - joined_at
  - total_posts_count

hidden_identity:
  - first_name
  - last_initial

# Other Objects/Entities serializers

post:
  # include multiple mixins:
  - with:
      - common_fields
      - engagement
  - title
  - body
  # If no serializer is given, all fields will be dumped to the output:
  - widgets
  - comments:
      # If a serializer is given, only the attributes defined in the schema will be included:
      - serializer: comment
  - author:
      - serializer: author
      - alias: author

comment:
  - with: common_fields
  - content
  - creator:
      # The root of this node will be "commenter" but the `creator` message will be sent to the `comment` object
      - alias: commenter
      # only include the first name, and last initial
      - serializer: hidden_identity

Serializing an Object

In your controller, use Donatello to serialize an object according to the schema:

class PostsController < ApplicationController
  # provides the "serialize" method. Note: Just put this in ApplicationController
  include Donatello

  def index
    render json: serialize(Post.all, :post)
    # or `current_user.posts` or `Post.first`, or a hash like `{ title: "Foo", ... }`

    # or `render json: { posts: serialize(Post.all) }
  end
end

This will produce JSON output like:

[{
  "id": "1",
  "title": "How to Defeat Shredder, and Look Good While Doing It.",
  "body": "Once upon a time, in a sewer ...",
  "author": {
    "first_name": "Master",
    "middle_initial": "P",
    "last_name": "Splinter",
    "total_posts_count": 25
  },
  "created_at": "...",
  "updated_at": "...",
  "comments": [{
    "content": "I'll get you Splinter!!!11~!~!",
    "creator": {
      "first_name": "Shred",
      "last_initial": "R"
    }
    // ...
  },{
    // ...
  }],
  "likes_count": 444,
  "comments_count": 33
},{
  // ...
}]

Contributing

Bug reports and pull requests are welcome on GitHub at [https://github.com/devfarm-io/donatello].

License

The gem is available as open source under the terms of the MIT License in this repo.