Giter Site home page Giter Site logo

json-exporter's Introduction

JSON Exporter

Simple to use and extend, versioned, nested objects support, data exporter.

Idea is simple

  • params passed to exporter are available via opts hash (with indifferent access)
  • response is available as hash (with indifferent access)

Installation

gem 'json-exporter'

Full example with all featuters annotated

We will do simple real life API json response formater. It needs to prepare values, filter and format the result.

class ApiExporter < JsonExporter
  before do
    opts[:full] ||= false
  end

  after do
    if json[:email]
      json[:email] = json[:email].downcase
    end
  end
end

class UserExporter < ApiExporter
  define do
    prop :name
    prop :email

    if opts[:full]
      prop :bio, 'Full user bio: %s' % model.bio
    end
  end
end

# usage and response

User = Struct.new(:name, :email, :bio)
user = User.new 'Dux', '[email protected]', 'charming chonker'

# UserExporter.export(user)
# -> {name:'Dux', email: '[email protected]'

# UserExporter.export(user, full: true)
# -> {name:'Dux', email: '[email protected]', bio: 'Full user bio: %s' % user.bio

Protected methods and variables

opts                      # passed in opts
before                    # run before export, modify opts
after                     # run before export, modify json response
prop or property          # add property to export model
model or @model           # passed in export model
json or @json or response # json response hash direct access
export                    # export other model, quick access

Features in detail

You can read the rspec test and get better insight on look and feel.

class JsonExporter
  # gets converted to
  # def before
  #   super
  #   meta[:version] ||= 1
  # end
  before do
    meta[:version] ||= 1
  end

  define Company do
    # copy :name property
    # same as -> prop :name, model.name
    # same as -> json[:name] = model.name
    prop :name

    # export user as creator property
    prop :creator, export(model.user)
  end

  # define exporter for User class,
  # JsonExporter(User)
  # JsonExporter.export(@user)
  # JsonExporter.new(@user).render
  define User do
    # proparty can be called by full name and can execute block
    prop :calc do
      # access passed @model vi @model or model
      # add
      model.num * 4
    end

    # same as - prop :company, export(model.company)
    # you can pass opts too - prop :company, export(model.company, full: true)
    export :company

    # attact full export of model.company as company_full property
    prop :company_full, export(model.company, full: true)

    # add prop only if opts version is 2+
    if opts.version > 2 do
      prop :extra, :value_1
    end
  end
end

Params in details + examples

  • model that is exported is available via @model or model
  • predefined methods
    • property (or prop) - export single property
    • export - export full model
    • json (or response) - add directly to response hash
  • class block before will define before filter for all objects. Useful to prepare opts before rendering
  • class block after will define after filter for all objects. Useful to add metadata to all objects
class JsonExporter
  # define custom exporter function
  def custom_foo
    if model.respond_to?(:baz)
      param :baz
    end
  end

  # add id and _meta property to all exported objects
  # after filter will run after transformation
  after do
    # every object has an ID, export it
    prop :id

    # call custom exporter function
    custom_foo

    # append medtadata
    json[:_meta] = {
      class: model.class.to_s,
      view_path: model.path,
      api_path: model.api_path
    }
  end

  # same as CompanyUser
  define :company_user do
  end

  define User do
    prop :name, model.name.capitalize

    # export
    export :company      # same as "prop :company, export(model.company)"
    export model.company # same if model.company class name is Company

    # you can add directly to response
    json[:foo]  = @user.foo
  end
end

Custom export names

Define multiple exporters, and pipe same object trough multiple exporters to get different results

class SomeExporter < JsonExporter
  define :foo_1 do
    # ...
  end

  define :foo_2 do
    # ...
  end
end

SomeExporter.export(@model, exporter: :foo_1)
SomeExporter.export(@model, exporter: :foo_2)

Suggested usage

simple cases (should be the usual case)

  • Create base class
  • Export all from there
class PetExporter < JsonExporter
  after do
    # ...
  end

  define Dog do
    # ...
  end
end

PetExporter.export(@dog)

extra exporter per class

If you name class DogPetExporter and export Dog via PetExporter, DogPetExporter class will be used.

class PetExporter < JsonExporter
  after do
    # ...
  end
end

class DogPetExporter < PetExporter
  define do
    # ...
  end
end

PetExporter.export(@dog) or DogPetExporter.export(@dog)

Tips

  • If you want to covert hash keys to string keys, for example to use in Liquid templateing, use @response.stringify_keys
  • If you do not want to use hash with indifferent access for response (https://github.com/dux/hash_wia), set JsonExporter.disable_wia!

json-exporter's People

Contributors

dux avatar

Stargazers

Tayyab Ashraf avatar alek_pol avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.