Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dux/json-exporter
Simple to use and extend, versioned, nested objects support, data exporter.
https://github.com/dux/json-exporter
Last synced: about 2 months ago
JSON representation
Simple to use and extend, versioned, nested objects support, data exporter.
- Host: GitHub
- URL: https://github.com/dux/json-exporter
- Owner: dux
- License: mit
- Created: 2020-08-02T10:30:44.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-10-26T00:19:40.000Z (about 1 year ago)
- Last Synced: 2024-03-15T12:11:58.680Z (10 months ago)
- Language: Ruby
- Homepage:
- Size: 39.1 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## 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.
```ruby
class ApiExporter < JsonExporter
before do
opts[:full] ||= false
endafter do
if json[:email]
json[:email] = json[:email].downcase
end
end
endclass UserExporter < ApiExporter
define do
prop :name
prop :emailif 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
```ruby
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](https://github.com/dux/json-exporter/blob/master/spec/tests/exporter_spec.rb)
and get better insight on look and feel.```ruby
class JsonExporter
# gets converted to
# def before
# super
# meta[:version] ||= 1
# end
before do
meta[:version] ||= 1
enddefine 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```ruby
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
enddefine 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
```ruby
class SomeExporter < JsonExporter
define :foo_1 do
# ...
enddefine :foo_2 do
# ...
end
endSomeExporter.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```ruby
class PetExporter < JsonExporter
after do
# ...
enddefine Dog do
# ...
end
endPetExporter.export(@dog)
```### extra exporter per class
If you name class `DogPetExporter` and export `Dog` via `PetExporter`,
`DogPetExporter` class will be used.```ruby
class PetExporter < JsonExporter
after do
# ...
end
endclass DogPetExporter < PetExporter
define do
# ...
end
endPetExporter.export(@dog) or DogPetExporter.export(@dog)
```## Tips
* If you want to covert hash keys to string keys, for example to use in
[Liquid templateing](https://shopify.github.io/liquid/), use `@response.stringify_keys`
* If you do not want to use hash with indifferent access for response
([https://github.com/dux/hash_wia](https://github.com/dux/hash_wia)), set `JsonExporter.disable_wia!`