Yes Read API
This gem implements an endpoint to query read models.
Installation
Add a gem to your Gemfile
gem 'yes-read-api'
and run bundle install
Usage
See the root README for the full DSL documentation and aggregate definition.
There are a few steps you need to do in order to integrate this gem. In the examples below we assume you have an Apprenticeship read model class. The module structure is strict.
- Mount gem's endpoint to use it. Example(in
routes.rb):
Rails.application.routes.draw do
mount Yes::Read::Api::Engine => '/queries'
end
- Define a set of registered models. You can do it as follows (in
application.rb)
config.yes_read_api.read_models = ['apprenticeships']
- Define an authorizer for your read model's request:
module ReadModels
module Apprenticeship
class RequestAuthorizer < Yes::Core::ReadModel::RequestAuthorizer
def self.call(params, auth_data)
auth_data['scopes'].include?('admin')
end
end
end
end
- Define a filter class for your read model. You can declare various ActiveRecord filters which can be applied to your collection based on request params. Assuming you have a
by_idscope in yourApprenticeshipmodel:
module ReadModels
module Apprenticeship
class Filter < Yes::Core::ReadModel::Filter
has_scope :ids do |controller, scope, value|
scope.by_id(value.split(','))
end
private
def read_model_class
::Apprenticeship
end
end
end
end
- Optional. Define an authorizer for your read model. You can inherit from
Yes::Core::ReadModelAuthorizeror define your own base class:
module ReadModels
module Apprenticeship
class Authorizer < ReadModels::Authorizer
class << self
def call(record, auth_data)
raise ReadModels::Authorizer::NotAuthorized, 'You need to be a company admin' unless company_admin?(auth_data)
true
end
end
end
end
end
Now you can query your read model via GET /queries/apprenticeships request.
Pagination
Read responses are always paginated. You can supply pagination parameter in case you want to change the default
| Name | Default |
|---|---|
| page[number] | 1 |
| page[size] | 20 |
| page[include_total] | false |
The read response includes pagination information in the following headers
| Name | Description |
|---|---|
| X-Page | page number |
| X-Per-Page | page size |
| X-Total | Total number of items. By default not included(null) If you need a total number set page[include_total] to true |
By default pagination is using countless_minimal mode.
The X-Total header is not returned in the response. Count query is not produced to DB.
You can change this behavior per each request by adding page[include_total]=true params to the request query.
If you wish to change the default behavior globally, so X-Total header is returned for the every request response by default, you can set globally Pagy::DEFAULT[:countless_minimal] = false or example in the pagy_initializer.rb. In this case page[include_total] param is ignored.
More you can read here: Pagy Countless
Development
Prerequisites
- Docker and Docker Compose
- Ruby >= 3.2.0
- Bundler
Setup
Start PostgreSQL from the repository root:
docker compose up -d
Install dependencies:
bundle install
Set up the test database:
RAILS_ENV=test bundle exec rake db:create db:migrate
The .env file at spec/dummy/.env is loaded automatically and contains JWT test keys and database configuration.
Running Specs
bundle exec rspec
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/yousty/yes.
License
The gem is available as open source under the terms of the MIT License.