JPie

Gem Version Build Status

JPie is a modern, lightweight Rails library for developing JSON:API compliant servers. It focuses on clean architecture with strong separation of concerns and extensibility.

Key Features

Modern Rails DSL - Clean, intuitive syntax following Rails conventions
🔧 Method Overrides - Define custom attribute methods directly on resource classes
🎯 Smart Inference - Automatic model and resource class detection
Powerful Generators - Scaffold resources with relationships, meta attributes, and automatic inference
📊 Polymorphic Support - Full support for complex polymorphic associations
🔄 STI Ready - Single Table Inheritance works out of the box
🔗 Through Associations - Full support for Rails :through associations
Performance Optimized - Efficient serialization with intelligent deduplication
🛡️ Authorization Ready - Built-in scoping support for security
📋 JSON:API Compliant - Full specification compliance with sorting, includes, and meta
🚨 Robust Error Handling - Smart inheritance-aware error handling with full customization options

Installation

Add JPie to your Rails application:

bundle add jpie

Development Setup

This project uses Overcommit to enforce code quality through Git hooks. After cloning the repository:

# One command to set up everything
./bin/setup-hooks

Manual Setup

If you prefer to set up manually:

# 1. Install dependencies
bundle install

# 2. Install overcommit globally (one-time setup)
gem install overcommit

# 3. Install the Git hooks for this project
overcommit --install

# 4. Sign the configuration (required for security)
overcommit --sign

3. Automated Quality Checks

The following checks run automatically:

Pre-commit hooks:

  • RuboCop - Code style and quality analysis
  • Trailing whitespace - Prevents whitespace issues
  • Merge conflicts - Catches unresolved conflicts

Pre-push hooks:

  • RSpec - Full test suite execution

4. Manual Quality Checks

You can run these checks manually:

# Run RuboCop with auto-fix
bundle exec rubocop -A

# Run tests
bundle exec rspec

# Test hooks without committing
overcommit --run pre-commit
overcommit --run pre-push

Quick Start

JPie works out of the box with minimal configuration:

1. Create Your Model

class User < ActiveRecord::Base
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true

  has_many :posts, dependent: :destroy
  has_one :profile, dependent: :destroy
end

2. Create Your Resource

class UserResource < JPie::Resource
  attributes :name, :email
  meta_attributes :created_at, :updated_at

  has_many :posts
  has_one :profile
end

3. Create Your Controller

class UsersController < ApplicationController
  include JPie::Controller
end

4. Set Up Routes

Rails.application.routes.draw do
  resources :users
end

That's it! You now have a fully functional JSON:API compliant server with automatic CRUD operations, sorting, includes, and validation.

📚 Comprehensive Examples

JPie includes a complete set of examples demonstrating all features:

Each example is self-contained with models, resources, controllers, and sample API requests/responses. 📋 View all examples →

Generators

JPie includes a resource generator for quickly creating new resource classes:

Basic Usage

# Generate a basic resource with semantic syntax
rails generate jpie:resource User attribute:name attribute:email meta:created_at

# Shorthand for relationships
rails generate jpie:resource Post attribute:title attribute:content has_many:comments has_one:author

# Mix explicit categorization with auto-detection
rails generate jpie:resource User attribute:name email created_at updated_at

Generated file:

class UserResource < JPie::Resource
  attributes :name, :email
  meta_attributes :created_at, :updated_at

  has_many :comments
  has_one :author
end

Semantic Field Syntax

Syntax Purpose Example
attribute:field Regular JSON:API attribute attribute:name
meta:field JSON:API meta attribute meta:created_at
has_many:resource JSON:API relationship has_many:posts
has_one:resource JSON:API relationship has_one:profile

Generator Options

Option Description Example
--model=NAME Specify model class --model=Person
--skip-model Skip explicit model declaration --skip-model

Modern DSL

class UserResource < JPie::Resource
  # Multiple attributes at once
  attributes :name, :email, :created_at

  # Meta attributes (for additional data)
  meta :account_status, :last_login

  # Relationships for includes
  has_many :posts
  has_one :profile

  # Custom sorting
  sortable :popularity do |query, direction|
    query.order(likes_count: direction)
  end

  # Custom attribute methods (modern approach)
  private

  def 
    object.active? ? 'active' : 'inactive'
  end
end

See the examples folder for more examples of how to use the DSL to solve various serialization/deserialization scenarios.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/emilkampp/jpie.

License

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