jsonapi-rb

Efficient and convenient JSON API library for ruby.

class SerializablePost < JSONAPI::Serializable::Resource
  type 'posts'

  attributes :title, :body

  attribute :date do
    @object.created_at
  end

  belongs_to :author

  has_many :comments do
    data do
      @object.published_comments
    end

    link :related do
      @url_helpers.user_posts_url(@object.id)
    end

    meta do
      { count: @object.published_comments.count }
    end
  end

  link :self do
    @url_helpers.post_url(@object.id)
  end

  meta do
    { featured: true }
  end
end
# Gemfile
gem 'jsonapi-rb'

# Serialization
require 'jsonapi/serializable'

renderer = JSONAPI::Serializable::Renderer.new

renderer.render(
  posts,
  class: { User: SerializableUser, Comment: SerializableComment },
  expose: { url_helpers: MyUrlHelper.new },
  include: [:author, comments: [:author]],
  fields: { users: [:name, :email] }
)
# => { data: [...], included: [...] }

# Deserialization
require 'jsonapi/deserializable'

resource = JSONAPI::Deserializable::Resource.new(json_hash)
resource.to_h
# => {
#      title: 'Welcome',
#      date: '2016-11-17',
#      author_id: '5',
#      author_type: 'users',
#      comments_ids: ['13', '29', '31'],
#      comments_types: ['comments', 'comments', 'comments']
#    }
# Gemfile
gem 'jsonapi-rails'

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  deserializable_resource :post, only: [:create, :update]

  def create_params
    params.require(:post).permit(:title, :content, :tag_ids)
  end

  def create
    post = Post.create(create_params)
    render jsonapi: post,
           include: [:author, comments: [:author]],
           fields: { users: [:name, :email] },
           status: :created
  end
end
# Gemfile
gem 'jsonapi-hanami'

# apps/api/controllers/posts/create.rb
module API::Controllers::Posts
  class Create
    include API::Action
    include JSONAPI::Hanami::Action

    deserializable_resource :post

    params do
      required(:post).schema do
        required(:title)
        required(:content)
        required(:tag_ids)
      end
    end

    def call(params)
      repo = PostRepository.new
      post = repo.create(params[:post])

      self.data = post
      self.include = [:author, comments: [:author]]
      self.fields = { users: [:name, :email] }
      self.status = 201
    end
  end
end