Hello. Enter the future of API development.

Pragma is an expressive, opinionated ecosystem for building beautiful RESTful APIs with Ruby. It creates a solid foundation for your API so that you can focus on the stuff that matters.

or
$ gem install pragma
$ curl 'https://my-api.com/api/v1/articles/1'

{
  "id": 1,
  "title": "Hello, world!",
  "body": "Isn't this awesome?",
  "published": true,
  "tags": ["pragma", "is", "cool"],
  "created_at": 1508096701,
  "created_at": 1508107498,
  "author": 1
}

Pragma::Policy

Resource authorization as simple as POROs.

module API
  module V1
    module Article
      class Policy < Pragma::Policy::Base
        class Scope < Pragma::Policy::Base::Scope
          def resolve
            scope.published.or(scope.written_by(user))
          end
        end

        def show?
          resource.published? || resource.author == user
        end

        def create?
          user.role == :author
        end

        def update?
          resource.author == user
        end

        def destroy?
          resource.author == user
        end
      end
    end
  end
end

Pragma::Contract

Like form objects but, you know, for APIs.

module API
  module V1
    module Article
      module Contract
        class Base < Pragma::Contract::Base
          property :title, type: coercible(:string)
          property :body, type: coercible(:string)
          property :published, type: strict(:bool)
          collection :tags

          validation do
            required(:title).filled(:str?)
            required(:body) { filled? & str? & min_length?(300) }
            required(:tags) { array? & each(:str?) & max_size?(10) }
            required(:published).filled(:bool?)
          end
        end

        class Create < Base
          property :send_newsletter,
            virtual: true,
            type: strict(:bool)
        end

        class Update < Base; end
      end
    end
  end
end

Pragma::Decorator

Powerful and elegant model presenters with a twist.

module API
  module V1
    module Article
      module Decorator
        class Instance < Pragma::Decorator::Base
          include Pragma::Decorator::Type
          include Pragma::Decorator::Timestamp
          include Pragma::Decorator::Association

          property :title
          property :body
          property :tags
          property :published

          timestamp :created_at
          timestamp :updated_at

          belongs_to :author, decorator: User::Decorator::Instance
        end

        class Collection < Pragma::Decorator::Base
          include Pragma::Decorator::Type
          include Pragma::Decorator::Collection
          include Pragma::Decorator::Pagination
        end
      end
    end
  end
end

Pragma::Operation

Endpoint encapsulation that doesn't get in the way.

module API
  module V1
    module Article
      module Operation
        class Index < Pragma::Operation::Index
          self['pagination.default_per_page'] = 10
          self['expand.enabled'] = false
          self['ordering.default_column'] = :updated_at
        end

        class Show < Pragma::Operation::Show; end

        class Create < Pragma::Operation::Create
          success :send_newsletter!

          def send_newsletter!(model:, **options)
            if options['result.contract.default'].send_newsletter
              SendArticleNewsletterJob.perform_later(model)
            end
          end
        end

        class Update < Pragma::Operation::Update; end

        class Destroy < Pragma::Operation::Destroy; end
      end
    end
  end
end

Simple. Powerful. Different.

Put the fun back into API development.

Pragma was built out of frustration with existing API toolkits. None of them really allowed me to focus on the business logic of my APIs, because I was constantly worrying about trivial tasks: how should I do pagination? How should I present validation errors? The list goes on and on. Over the years, I have come up with a standardized way of doing things, one that is flexible and elegant.

That's how Pragma was born.

Building a new API resource with Pragma takes literally five minutes, tests included. Don't believe me? See it for yourself. By abstracting away all the usual chores around API building, while still providing a powerful DSL for customization, Pragma lets you focus on The Important Stuff.

Better by design.

Wondering how we score against the competition?

Pragma Grape Rails::API rocket_pants JR
Authorization
Generators
Collection rendering
Pagination
Commercial support
Training
Built-in CRUD
Rails template
Coercion
Error handling
Associations
Versioning
Introspection

Hey, what's up?

My name is Alessandro and I'm the author of Pragma. I've been building APIs for as far as I remember. Well, maybe not that long, just for the past five years. Pragma was created out of love for the community — if you are using Pragma in your project, have a feature request or just want to chat about software development, writing or photography, drop me a line!