All Projects → getbannerman → babl

getbannerman / babl

Licence: MIT license
JSON templating on steroids

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to babl

Html
A Virtual DOM based templating-engine for PHP
Stars: ✭ 86 (+196.55%)
Mutual labels:  immutable, functional, template-engine
Fpp
Functional PHP Preprocessor - Generate Immutable Data Types
Stars: ✭ 282 (+872.41%)
Mutual labels:  immutable, functional
Typed Immutable
Immutable and structurally typed data
Stars: ✭ 263 (+806.9%)
Mutual labels:  immutable, functional
Immutable Tuple
Immutable finite list objects with constant-time equality testing (===) and no memory leaks.
Stars: ✭ 29 (+0%)
Mutual labels:  immutable, functional
finger-tree
🌵 Finger tree data structure for JavaScript
Stars: ✭ 20 (-31.03%)
Mutual labels:  immutable, functional
venum
Verifiably better, validated Enum for Python
Stars: ✭ 31 (+6.9%)
Mutual labels:  immutable, functional
Partial.lenses
Partial lenses is a comprehensive, high-performance optics library for JavaScript
Stars: ✭ 846 (+2817.24%)
Mutual labels:  immutable, functional
peds
Type safe persistent/immutable data structures for Go
Stars: ✭ 57 (+96.55%)
Mutual labels:  immutable, functional
Pyrsistent
Persistent/Immutable/Functional data structures for Python
Stars: ✭ 1,621 (+5489.66%)
Mutual labels:  immutable, functional
Typed
The TypeScript Standard Library
Stars: ✭ 124 (+327.59%)
Mutual labels:  immutable, functional
100 Lines Of Code Challenge Js
Write Everything in JavaScript under 100 Lines!!!😈
Stars: ✭ 157 (+441.38%)
Mutual labels:  immutable, template-engine
fastener
Functional Zipper for manipulating JSON
Stars: ✭ 54 (+86.21%)
Mutual labels:  immutable, functional
php-json-schema-model-generator
Creates (immutable) PHP model classes from JSON-Schema files including all validation rules as PHP code
Stars: ✭ 36 (+24.14%)
Mutual labels:  immutable, json-schema
Switzerland
🇨🇭Switzerland takes a functional approach to Web Components by applying middleware to your components. Supports Redux, attribute mutations, CSS variables, React-esque setState/state, etc… out-of-the-box, along with Shadow DOM for style encapsulation and Custom Elements for interoperability.
Stars: ✭ 261 (+800%)
Mutual labels:  immutable, functional
treecko
A collection of functional and immutable helpers for working with tree data structures.
Stars: ✭ 31 (+6.9%)
Mutual labels:  immutable, functional
Phpfn
Functional PHP Toolstet: Centralized monorepository for all libraries
Stars: ✭ 19 (-34.48%)
Mutual labels:  immutable, functional
grand central
State-management and action-dispatching for Ruby apps
Stars: ✭ 20 (-31.03%)
Mutual labels:  immutable, functional
transmute
kind of like lodash but works with Immutable
Stars: ✭ 35 (+20.69%)
Mutual labels:  immutable, functional
js-data-structures
🌿 Data structures for JavaScript
Stars: ✭ 56 (+93.1%)
Mutual labels:  immutable, functional
HTML-templating-with-Google-Apps-Script
Use data from your spreadsheets to build a webpage or a client-side app ✨
Stars: ✭ 55 (+89.66%)
Mutual labels:  template-engine

BABL Logo

Build Status Coverage Status Gem Downloads

BABL (Bannerman API Builder Language) is a functional Ruby DSL for generating JSON in APIs.

It plays a role similar to RABL, JBuilder, Grape Entity, AMS, and many others.

Example

gem install babl-json
require 'babl'
require 'date'

Author = Struct.new(:name, :birthyear)
Article = Struct.new(:author, :title, :body, :date, :comments)
Comment = Struct.new(:author, :date, :body)

# Let's define some data
data = [
    Article.new(
        Author.new("Fred", 1990),
        'Introducing BABL',
        'Blablabla',
        DateTime.now,
        [
            Comment.new(
                Author.new("Luke", 1991),
                DateTime.now,
                'Great gem'
            )
        ]
    )
]

# Define a template
template = Babl.source {

    # A template can be stored in a variable ("inline partial") and re-used later.
    # For instance, this one serializes an Author.
    author = object(
        name: _,
        birthyear: _
    )

    # Produce a JSON object
    object(

        # Visit each article of from collection and produce a JSON object for each elements
        articles: each.object(

            # nav(:iso8601) can also be seen as a method call.
            # The method #iso8601 will be called on the date during rendering.
            date: _.nav(:iso8601),

            # '_' is a shortcut for 'nav(:title)' and 'nav(:body)'
            title: _,
            body: _,

            # You can chain another template using call()
            author: _.call(author),

            # Visit each comment, and produce a JSON object for each of them.
            comments: _.each.object(

                # In Ruby, .() is just a syntax sugar for .call()
                author: _.(author),

                # Type assertions can be (optionally) specified.
                # - They add runtime type checks
                # - They are added to JSON-Schema
                body: _.string,
                date: _.nav(:iso8601).string
            )
        )
    )
}

# All the magic happens here: the template is transformed into a fast serializer.
compiled_template = template.compile

# Serialize some data into JSON
compiled_template.json(data)

# =>
# {
#     "articles":[
#       {
#         "date":"2017-09-07T08:42:42+02:00",
#         "title":"Introducing BABL",
#         "body":"Blablabla",
#         "author":{
#           "name":"Fred",
#           "birthyear":1990
#         },
#         "comments":[
#           {
#             "author":{
#               "name":"Luke",
#               "birthyear":1991
#             },
#             "body":"Great gem",
#             "date":"2017-09-07T08:42:42+02:00"
#           }
#         ]
#       }
#     ]
#   }

# render() is like json(), but produces a Hash instead of a JSON
compiled_template.render(data)

# Output a JSON-Schema description of the template
compiled_template.json_schema

Benchmark

                                     user     system      total        real
RABL                             3.180000   0.010000   3.190000 (  3.189780)
JBuilder                         0.700000   0.000000   0.700000 (  0.708928)
BABL                             0.540000   0.000000   0.540000 (  0.540724)
BABL (compiled once)             0.410000   0.010000   0.420000 (  0.412431)
Handwritten Ruby                 0.080000   0.000000   0.080000 (  0.081407)

Results using code generation [WIP]:

                                     user     system      total        real
BABL (compiled once + codegen)   0.170000   0.000000   0.170000 (  0.168479)

See source code.

Features

Template compilation

A BABL template has to be compiled before it can be used. This approach carries several advantages:

  • Many errors can be detected earlier during the development process.
  • Partials are resolved only once, during compilation: zero overhead at render time.
  • Template fragments which are provably constant are pre-rendered at compilation time.
  • Code generation [WIP] should bring performances close to handcrafted Ruby code.

Automatic documentation (JSON schema)

BABL can automatically document a template by generating a JSON-Schema. Combined with optional type-checking assertions, it becomes possible to do some exciting things.

For instance, it is possible to generate TypeScript interfaces by feeding the exported JSON-Schema to https://github.com/bcherny/json-schema-to-typescript.

See how to generate a JSON-Schema.

Dependency analysis (automatic preloading)

Due to the static nature of BABL templates, it is possible to determine in advance which methods will be called on models objects during rendering. This is called dependency analysis. In practice, the extracted dependencies can be passed to a preloader, in order to avoid all N+1 issues.

Please note that this requires a compatible preloader implementation. At Bannerman, we are using Preeloo. It natively supports ActiveRecord associations, computed columns, and custom preloadable properties. Unfortunately, it hasn't been released publicly (yet), because it still has bugs and limitations.

Resources

License

Copyright (c) 2017 Bannerman, Frederic Terrazzoni

Licensed under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].