Convert Figma logo to code with AI

procore-oss logoblueprinter

Simple, Fast, and Declarative Serialization Library for Ruby

1,110
107
1,110
15

Top Related Projects

HTTP API design guide extracted from work on the Heroku Platform API

2,099

JSON Schema tools and doc generation for HTTP APIs

Quick Overview

Blueprinter is a Ruby gem that provides a simple and flexible way to generate JSON responses from Ruby objects. It aims to simplify the process of serializing data and managing complex object relationships, making it easier to build RESTful APIs.

Pros

  • Simplicity: Blueprinter offers a straightforward and intuitive API for defining object serialization, making it easy to use and integrate into existing projects.
  • Flexibility: The gem supports a wide range of features, including nested objects, conditional fields, and custom field transformations, allowing developers to customize the serialization process to their specific needs.
  • Performance: Blueprinter is designed to be efficient, with features like lazy loading and automatic memoization to improve performance and reduce resource usage.
  • Testability: The gem's modular design and clear separation of concerns make it easier to write unit tests for serialization logic, improving the overall quality and maintainability of the codebase.

Cons

  • Learning Curve: While the API is relatively simple, developers new to Blueprinter may need to invest some time in understanding the gem's concepts and conventions, especially when dealing with more complex serialization requirements.
  • Limited Ecosystem: Compared to some other popular Ruby serialization libraries, Blueprinter has a smaller ecosystem of third-party integrations and community support, which may limit its adoption in certain environments.
  • Dependency on Ruby: As a Ruby-specific library, Blueprinter is not directly applicable to projects in other programming languages, which may limit its usefulness for teams working with a polyglot technology stack.
  • Potential Performance Overhead: While Blueprinter is designed to be efficient, the additional abstraction and indirection introduced by the library may result in some performance overhead compared to more manual serialization approaches, especially for simple use cases.

Code Examples

Here are a few examples of how to use Blueprinter:

  1. Basic Object Serialization:
class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
end

user = User.find(1)
UserBlueprint.render(user)
# Output: {"id":1,"name":"John Doe","email":"john.doe@example.com"}
  1. Nested Object Serialization:
class AddressBlueprint < Blueprinter::Base
  fields :street, :city, :state, :zip
end

class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
  association :address, blueprint: AddressBlueprint
end

user = User.find(1)
UserBlueprint.render(user)
# Output: {"id":1,"name":"John Doe","email":"john.doe@example.com","address":{"street":"123 Main St","city":"Anytown","state":"CA","zip":"12345"}}
  1. Conditional Field Rendering:
class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
  field :admin?, if: ->(user, _options) { user.admin? }
end

user = User.find(1)
UserBlueprint.render(user)
# Output: {"id":1,"name":"John Doe","email":"john.doe@example.com","admin":true}

Getting Started

To get started with Blueprinter, add the gem to your Gemfile:

gem 'blueprinter'

Then, create a blueprint for your Ruby object:

class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
end

Finally, use the blueprint to render your object:

user = User.find(1)
UserBlueprint.render(user)
# Output: {"id":1,"name":"John Doe","email":"john.doe@example.com"}

For more advanced usage, refer to the Blueprinter documentation.

Competitor Comparisons

HTTP API design guide extracted from work on the Heroku Platform API

Pros of interagent/http-api-design

  • Provides a comprehensive guide for designing RESTful HTTP APIs, covering best practices and principles.
  • Emphasizes the importance of consistent and intuitive API design, which can improve developer experience and adoption.
  • Offers guidance on versioning, error handling, and other important aspects of API design.

Cons of interagent/http-api-design

  • Focuses solely on HTTP API design, while Blueprinter is a more general-purpose serialization library.
  • May not be as actively maintained or updated as Blueprinter, which has a larger community and more frequent releases.
  • Doesn't provide any code-level implementation details or examples, unlike Blueprinter which includes sample code.

Code Comparison

Blueprinter (procore-oss/blueprinter):

class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
  association :posts, blueprint: PostBlueprint
end

interagent/http-api-design:

No code examples are provided in the interagent/http-api-design repository. The project is focused on design guidelines and best practices for HTTP APIs.
2,099

JSON Schema tools and doc generation for HTTP APIs

Pros of PRMD

  • PRMD provides a more comprehensive set of features for defining and documenting API schemas, including support for JSON Schema and Swagger/OpenAPI.
  • PRMD has a larger and more active community, with more contributors and a longer history of development.
  • PRMD's documentation is more detailed and covers a wider range of use cases.

Cons of PRMD

  • PRMD has a steeper learning curve and may be more complex to set up and configure than Blueprinter.
  • PRMD is primarily focused on API documentation, while Blueprinter is a more general-purpose serialization library.
  • PRMD may have a larger dependency footprint and require more configuration than Blueprinter.

Code Comparison

Blueprinter:

class UserBlueprint < Blueprinter::Base
  identifier :id
  fields :name, :email
end

user = User.find(1)
json = UserBlueprint.render(user)

PRMD:

# Define the schema
schema = {
  type: 'object',
  properties: {
    id: { type: 'integer' },
    name: { type: 'string' },
    email: { type: 'string' }
  }
}

# Generate the documentation
prmd generate schema.json > api.md

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Test Gem Version Discord

Recent Organization Move

Please change your local remote to pull from this repository:

git remote set-url [previous-remote-name] git@github.com:procore-oss/blueprinter.git

to see the previous upstream remote name, run:

git remote -v

Blueprinter

Blueprinter is a JSON Object Presenter for Ruby that takes business objects and breaks them down into simple hashes and serializes them to JSON. It can be used in Rails in place of other serializers (like JBuilder or ActiveModelSerializers). It is designed to be simple, direct, and performant.

It heavily relies on the idea of views which, similar to Rails views, are ways of predefining output for data in different contexts.

Documentation

Docs can be found here.

Usage

Basic

If you have an object you would like serialized, simply create a blueprint. Say, for example, you have a User record with the following attributes [:uuid, :email, :first_name, :last_name, :password, :address].

You may define a simple blueprint like so:

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  fields :first_name, :last_name, :email
end

and then, in your code:

puts UserBlueprint.render(user) # Output is a JSON string

And the output would look like:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "email": "john.doe@some.fake.email.domain",
  "first_name": "John",
  "last_name": "Doe"
}
Collections

You can also pass a collection object or an array to the render method.

puts UserBlueprint.render(User.all)

This will result in JSON that looks something like this:

[
  {
    "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
    "email": "john.doe@some.fake.email.domain",
    "first_name": "John",
    "last_name": "Doe"
  },
  {
    "uuid": "733f0758-8f21-4719-875f-743af262c3ec",
    "email": "john.doe.2@some.fake.email.domain",
    "first_name": "John",
    "last_name": "Doe 2"
  }
]

You can also configure other classes to be treated like collections. For example, if you are using Mongoid, you can configure it to treat Mongoid::Criteria objects as collections:

Blueprinter.configure do |config|
  config.custom_array_like_classes = [Mongoid::Criteria]
end

Or if you wanted it to treat the Set class as a collection:

Blueprinter.configure do |config|
  config.custom_array_like_classes = [Set]
end
Renaming

You can rename the resulting JSON keys in both fields and associations by using the name option.

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  field :email, name: :login

  association :user_projects, name: :projects
end

This will result in JSON that looks something like this:

{
  "uuid": "92a5c732-2874-41e4-98fc-4123cd6cfa86",
  "login": "my@email.com",
  "projects": []
}
Views

You may define different outputs by utilizing views:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :first_name, :last_name
  end

  view :extended do
    include_view :normal
    field :address
    association :projects
  end
end

A view can include fields from another view by utilizing include_view and include_views.

Usage:

puts UserBlueprint.render(user, view: :extended)

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "address": "123 Fake St.",
  "first_name": "John",
  "last_name": "Doe",
  "login": "john.doe@some.fake.email.domain"
}
Identifiers

identifiers are used to specify a field or method name used as an identifier. Usually, this is something like :id.

Example:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
end

Blueprinter identifiers have a few properties that set them apart from fields.

  1. Identifiers are always rendered and considered their own view (the :identifier view).
  2. When rendering, identifier fields are always sorted first, before other fields.

If either of the above two developer conveniences are not desired, you can simply create your identifier fields as regular fields.

Root

You can also optionally pass in a root key to wrap your resulting json in:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :first_name, :last_name
  end
end

Usage:

puts UserBlueprint.render(user, view: :normal, root: :user)

Output:

{
  "user": {
    "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
    "first_name": "John",
    "last_name": "Doe",
    "login": "john.doe@some.fake.email.domain"
  }
}
Meta Attributes

You can additionally add meta-data to the json as well:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :first_name, :last_name
  end
end

Usage:

json = UserBlueprint.render(user, view: :normal, root: :user, meta: {links: [
  'https://app.mydomain.com',
  'https://alternate.mydomain.com'
]})
puts json

Output:

{
  "user": {
    "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
    "first_name": "John",
    "last_name": "Doe",
    "login": "john.doe@some.fake.email.domain"
  },
  "meta": {
    "links": [
      "https://app.mydomain.com",
      "https://alternate.mydomain.com"
    ]
  }
}

NOTE: For meta attributes, a root is mandatory.

Exclude Fields

You can specifically choose to exclude certain fields for specific views

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :first_name, :last_name
  end

  view :extended do
    include_view :normal
    field :address
    exclude :last_name
  end
end

Usage:

puts UserBlueprint.render(user, view: :extended)

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "address": "123 Fake St.",
  "first_name": "John",
  "login": "john.doe@some.fake.email.domain"
}

Use excludes to exclude multiple fields at once inline.

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :age, :first_name, :last_name,
  end

  view :extended do
    include_view :normal
    field :address
    excludes :age, :last_name
  end
end
Associations

You may include associated objects. Say for example, a user has projects:

class ProjectBlueprint < Blueprinter::Base
  identifier :uuid
  field :name
end

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :email, name: :login

  view :normal do
    fields :first_name, :last_name
    association :projects, blueprint: ProjectBlueprint
  end
end

Usage:

puts UserBlueprint.render(user, view: :normal)

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "first_name": "John",
  "last_name": "Doe",
  "login": "john.doe@some.fake.email.domain",
  "projects": [
    {
      "uuid": "dca94051-4195-42bc-a9aa-eb99f7723c82",
      "name": "Beach Cleanup"
    },
    {
      "uuid": "eb881bb5-9a51-4d27-8a29-b264c30e6160",
      "name": "Storefront Revamp"
    }
  ]
}

It is also possible to pass options from one Blueprint to another via an association. For example:

class VehicleBlueprint < Blueprinter::Base
  identifier :uuid
  field :full_name do |vehicle, options|
    "#{vehicle.model} #{options[:trim]}"
  end
end

class DriverBlueprint < Blueprinter::Base
  identifier :uuid

  view :normal do
    fields :first_name, :last_name
    association :vehicles, blueprint: VehicleBlueprint, options: { trim: 'LX' }
  end
end
Default Association/Field Option

By default, an association or field that evaluates to nil is serialized as nil. A default serialized value can be specified as an option on the association or field for cases when the association/field could potentially evaluate to nil. You can also specify a global field_default or association_default in the Blueprinter config which will be used for all fields/associations that evaluate to nil.

Global Config Setting

Blueprinter.configure do |config|
  config.field_default = "N/A"
  config.association_default = {}
end

Field-level/Association-level Setting

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  view :normal do
    field :first_name, default: "N/A"
    association :company, blueprint: CompanyBlueprint, default: {}
  end
end
default_if

Sometimes, you may want certain "empty" values to pass through to the default value. Blueprinter provides the ability to treat the following empty types as the default value (or nil if no default provided).

Blueprinter::EMPTY_COLLECTION

An empty array or empty active record collection.

Blueprinter::EMPTY_HASH

An empty hash.

Blueprinter::EMPTY_STRING

An empty string or symbol.

Field-level/Association-level Setting - EMPTY_STRING

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  view :normal do
    # If first_name is an empty string, it will become "N/A"
    field :first_name, default_if: Blueprinter::EMPTY_STRING, default: "N/A"
    # If the projects association collection is empty, it will become nil
    association :projects, blueprint: ProjectBlueprint, default_if: Blueprinter::EMPTY_COLLECTION
  end
end
Supporting Dynamic Blueprints For Associations

When defining an association, we can dynamically evaluate the blueprint. This comes in handy when adding polymorphic associations, by allowing reuse of existing blueprints.

class Task < ActiveRecord::Base
  belongs_to :taskable, polymorphic: true
end

class Project < ActiveRecord::Base
  has_many :tasks, as: :taskable

  def blueprint
    ProjectBlueprint
  end
end

class TaskBlueprint < Blueprinter::Base
  identifier :uuid

  view :normal do
    field :title, default: "N/A"
    association :taskable, blueprint: ->(taskable) {taskable.blueprint}, default: {}
  end
end

NOTE: taskable.blueprint should return a valid Blueprint class. Currently, has_many is not supported because of the very nature of polymorphic associations.

Defining A Field Directly In The Blueprint

You can define a field directly in the Blueprint by passing it a block. This is especially useful if the object does not already have such an attribute or method defined, and you want to define it specifically for use with the Blueprint. This is done by passing field a block. The block also yields the object and any options that were passed from render. For example:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :full_name do |user, options|
    "#{options[:title_prefix]} #{user.first_name} #{user.last_name}"
  end
end

Usage:

puts UserBlueprint.render(user, title_prefix: "Mr")

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "full_name": "Mr John Doe"
}
Defining An Identifier Directly In The Blueprint

You can also pass a block to an identifier:

class UserBlueprint < Blueprinter::Base
  identifier :uuid do |user, options|
    options[:current_user].anonymize(user.uuid)
  end
end

Usage:

puts UserBlueprint.render(user, current_user: current_user)

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
}
Defining An Association Directly In The Blueprint

You can also pass a block to an association:

class ProjectBlueprint < Blueprinter::Base
  identifier :uuid
  field :name
end

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  association :projects, blueprint: ProjectBlueprint do |user, options|
    user.projects + options[:draft_projects]
  end
end

Usage:

puts UserBlueprint.render(user, draft_projects: Project.where(draft: true))

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "projects": [
    {"uuid": "b426a1e6-ac41-45ab-bfef-970b9a0b4289", "name": "query-console"},
    {"uuid": "5bd84d6c-4fd2-4e36-ae31-c137e39be542", "name": "blueprinter"},
    {"uuid": "785f5cd4-7d8d-4779-a6dd-ec5eab440eff", "name": "uncontrollable"}
  ]
}
Passing Additional Properties To #render

render takes an options hash which you can pass additional properties, allowing you to utilize those additional properties in the field block. For example:

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field(:company_name) do |_user, options|
    options[:company].name
  end
end

Usage:

puts UserBlueprint.render(user, company: company)

Output:

{
  "uuid": "733f0758-8f21-4719-875f-262c3ec743af",
  "company_name": "My Company LLC"
}
Conditional Fields

Both the field and the global Blueprinter Configuration supports :if and :unless options that can be used to serialize fields conditionally.

Global Config Setting - if and unless

Blueprinter.configure do |config|
  config.if = ->(field_name, obj, _options) { !obj[field_name].nil? }
  config.unless = ->(field_name, obj, _options) { obj[field_name].nil? }
end

Field-level Setting

class UserBlueprint < Blueprinter::Base
  identifier :uuid
  field :last_name, if: ->(_field_name, user, options) { user.first_name != options[:first_name] }
  field :age, unless: ->(_field_name, user, _options) { user.age < 18 }
end

NOTE: The field-level setting overrides the global config setting (for the field) if both are set.

Exclude Fields with nil Values

By default, fields with nil values are included when rendering. You can override this behavior by setting :exclude_if_nil: true in the field definition.

Usage:

class UserBlueprint < Blueprinter::Base
  identifier :uuid

  field :name
  field :birthday, exclude_if_nil: true
end

user = User.new(name: 'John Doe')
puts UserBlueprint.render(user)

Output:

{
  "name": "John Doe"
}
Custom Formatting for Dates and Times

To define a custom format for a Date or DateTime field, include the option datetime_format. This global or field-level option can be either a string representing the associated strftime format, or a Proc which receives the original Date/DateTime object and returns the formatted value. When using a Proc, it is the Proc's responsibility to handle any errors in formatting.

Global Config Setting - datetime

If a global datetime_format is set (either as a string format or a Proc), this option will be invoked and used to format all fields that respond to strftime.

Blueprinter.configure do |config|
  config.datetime_format = ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
end

Field-level Setting - datetime_format

Usage (String Option):

class UserBlueprint < Blueprinter::Base
  identifier :name
  field :birthday, datetime_format: "%m/%d/%Y"
end

Output:

{
  "name": "John Doe",
  "birthday": "03/04/1994"
}

Usage (Proc Option):

class UserBlueprint < Blueprinter::Base
  identifier :name
  field :birthday, datetime_format: ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i }
end

Output:

{
  "name": "John Doe",
  "birthday": 762739200
}

NOTE: The field-level setting overrides the global config setting (for the field) if both are set.

Transform Classes

Blueprinter provides the ability to specify transforms on views, which enable further processing and transforming of resulting view field hashes prior to serialization.

Use transform to specify one transformer to be included for serialization. A transformer is a class, extending Blueprinter::Transformer and implementing the transform method. The modified hash object will be the resulting hash passed to serialization.

Example

Create a Transform class extending from Blueprinter::Transformer

class DynamicFieldTransformer < Blueprinter::Transformer
  def transform(hash, object, _options)
    hash.merge!(object.dynamic_fields)
  end
end
class User
  def dynamic_fields
    case role
    when :admin
      {
        employer: employer,
        time_in_role: determine_time_in role
      }
    when :maintainer
      {
        label: label,
        settings: generate_settings_hash
      }
    when :read_only
      {
        last_login_at: last_login_at
      }
    end
  end
end

Then specify the transform to use for the view.

class UserBlueprint < Blueprinter::Base
  fields :first_name, :last_name
  transform DynamicTransformer
end

Transform across views

Transformers can be included across views:

class UserBlueprint < Blueprinter::Base
  transform DefaultTransformer

  view :normal do
    transform ViewTransformer
  end

  view :extended do
    include_view :normal
  end
end

Both the normal and extended views have DefaultTransformer and ViewTransformer applied.

Transformers are executed in a top-down order, so DefaultTransformer will be executed first, followed by ViewTransformer.

Global Transforms

You can also specify global default transformers. Create one or more transformer classes extending from Blueprinter::Transformer and set the default_transformers configuration

class LowerCamelTransformer < Blueprinter::Transformer
  def transform(hash, _object, _options)
    hash.transform_keys! { |key| key.to_s.camelize(:lower).to_sym }
  end
end
Blueprinter.configure do |config|
  config.default_transformers = [LowerCamelTransformer]
end

Note: Any transforms specified on a per-blueprint or per-view level will override the default_transformers in the configuration.

Configurable Extractors

Blueprinter gets a given objects' values from the fields definitions using extractor classes. You can substitute your own extractor class globally or per-field.

Examples

For a specific kind of field, create an extractor class extending from Blueprinter::Extractor

class MyFieldExtractor < Blueprinter::Extractor
  def extract(_field_name, _object, _local_options, _options={})
    # process your obscure_object
    _object.clarified
  end
end
class MysteryBlueprint < Blueprinter::Base
  field :obscure_object, extractor: MyFieldExtractor
end

For a global default, create an extractor class extending from Blueprinter::AutoExtractor and set the extractor_default configuration

class MyAutoExtractor < Blueprinter::AutoExtractor
  def initialize
    super
    @my_field_extractor = MyFieldExtractor.new
  end
  def extractor(object, options)
    # dispatch to any class AutoExtractor can, plus more
    if detect_obscurity(object)
      @my_field_extractor
    else
      super
    end
  end
end
Blueprinter.configure do |config|
  config.extractor_default = MyAutoExtractor
end
Sorting Fields

By default the response sorts the keys by name. If you want the fields to be sorted in the order of definition, use the below configuration option.

Usage:

Blueprinter.configure do |config|
  config.sort_fields_by = :definition
end
class UserBlueprint < Blueprinter::Base
  identifier :name
  field :email
  field :birthday, datetime_format: "%m/%d/%Y"
end

Output:

{
  "name": "John Doe",
  "email": "john.doe@some.fake.email.domain",
  "birthday": "03/04/1994"
}
Reflection

Blueprint classes may be reflected on to inspect their views, fields, and associations. Extensions often make use of this ability.

class WidgetBlueprint < Blueprinter::Base
  fields :name, :description
  association :category, blueprint: CategoryBlueprint

  view :extended do
    field :price
    association :parts, blueprint: WidgetPartBlueprint
  end
end

# A Hash of views keyed by name
views = WidgetBlueprint.reflections
views.keys
=> [:default, :extended]

# Hashes of fields and associations, keyed by name
fields = views[:default].fields
assoc = views[:default].associations

# Get info about a field
fields[:description].name
fields[:description].display_name
fields[:description].options

# Get info about an association
assoc[:category].name
assoc[:category].display_name
assoc[:category].blueprint
assoc[:category].view
assoc[:category].options
Extensions

Blueprinter offers an extension system to hook into and modify certain behavior.

Blueprinter.configure do |config|
  config.extensions << MyExtension.new
  config.extensions << OtherExtension.new
end

Extension hooks:

  • pre_render: Intercept the object before rendering begins

Some known extensions are:

Deprecations

When functionality in Blueprinter is invoked, that has been deprecated, the default behavior is to write a deprecation notice to stderror.

However, deprecations can be configured to report at three different levels:

KeyResult
:stderr (Default)Deprecations will be written to stderror
:raiseDeprecations will be raised as Blueprinter::BlueprinterErrors
:silenceDeprecations will be silenced and will not be raised or logged

Example - deprecations

Blueprinter.configure do |config|
  config.deprecations = :raise
end
render_as_hash

Same as render, returns a Ruby Hash.

Usage:

puts UserBlueprint.render_as_hash(user, company: company)

Output:

{
  uuid: "733f0758-8f21-4719-875f-262c3ec743af",
  company_name: "My Company LLC"
}
render_as_json

Same as render, returns a Ruby Hash JSONified. This will call JSONify all keys and values.

Usage:

puts UserBlueprint.render_as_json(user, company: company)

Output:

{
  "uuid" => "733f0758-8f21-4719-875f-262c3ec743af",
  "company_name" => "My Company LLC"
}

Installation

Add this line to your application's Gemfile:

gem 'blueprinter'

And then execute:

bundle

Or install it yourself as:

gem install blueprinter

You should also have require 'json' already in your project if you are not using Rails or if you are not using Oj.

OJ

By default, Blueprinter will be calling JSON.generate(object) internally and it expects that you have require 'json' already in your project's code. You may use Oj to generate in place of JSON like so:

require 'oj' # you can skip this if OJ has already been required.

Blueprinter.configure do |config|
  config.generator = Oj # default is JSON
end

Ensure that you have the Oj gem installed in your Gemfile if you haven't already:

# Gemfile
gem 'oj'

Yajl-ruby

yajl-ruby is a fast and powerful JSON generator/parser. To use yajl-ruby in place of JSON / OJ, use:

require 'yajl' # you can skip this if yajl has already been required.

Blueprinter.configure do |config|
  config.generator = Yajl::Encoder # default is JSON
  config.method = :encode # default is generate
end

NOTE: You should be doing this only if you aren't using yajl-ruby through the JSON API by requiring yajl/json_gem. More details here. In this case, JSON.generate is patched to use Yajl::Encoder.encode internally.

Contributing

Please read our Contributing file

Tests

You can run tests with bundle exec rake.

Maintain The Docs

We use Yard for documentation. Here are the following documentation rules:

  • Document all public methods we expect to be utilized by the end developers.
  • Methods that are not set to private due to ruby visibility rule limitations should be marked with @api private.

How to Document

We use Yard for documentation. Here are the following documentation rules:

  • Document all public methods we expect to be utilized by the end developers.
  • Methods that are not set to private due to ruby visibility rule limitations should be marked with @api private.

Releasing a New Version

To release a new version, change the version number in version.rb, and update the CHANGELOG.md. Finally, maintainers need to run bundle exec rake release, which will automatically create a git tag for the version, push git commits and tags to Github, and push the .gem file to rubygems.org.

License

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

NPM DownloadsLast 30 Days