Usage Without ActiveRecord: HTTP Services
This is a commonly requested example. Instead of using a full-fledged
client like ActiveRecord
or Trample
, we’ll show low-level usage that
could apply to a variety of HTTP clients.
Remember, we always start with a “base scope” and modify that scope depending on incoming request parameters. This same pattern could apply to simply ruby hashes.
def index
render_jsonapi({})
end
Let’s start by specifying a Null
adapter - a pass-through adapter that
won’t do anything without us explicitly overriding:
# config/initializers/jsonapi.rb
require 'jsonapi_compliable/adapters/null'
# app/resources/post_resource.rb
use_adapter JsonapiCompliable::Adapters::Null
Every time we get a request to sort, paginate, etc we’ll need to modify our hash. Here we’ll simply merge parameters in the format our HTTP client will accept:
# app/resources/post_resource.rb
allow_filter :title do |scope, value|
scope.merge!(conditions: { title: value })
end
sort do |scope, attribute, direction|
scope.merge!(order: { attribute => direction })
end
paginate do |scope, current_page, per_page|
offset = (current_page * per_page) - per_page
scope.merge!(limit: per_page, offset: offset)
end
Finally, we need to tell the resorce how to resolve the query. In our case, this means passing the built-up parameters into a method on our HTTP client.
# app/resources/post_resource.rb
# Remember, 'scope' here is a hash
def resolve(scope)
results = MyHTTPClient.get(scope)
results.map { |r| Post.new(r) }
end
Note that #resolve must return an array of Model
instances. These
can be simple POROs, as you see above.
The final request would look something like this:
HTTPClient.get \
conditions: { title: "Hello World!" },
order: { created_at: :desc },
limit: 10,
offset: 20
In our controller, if we used the lower-level jsonapi_scope method to introspect our results, we’d see an array of Post
instances:
# app/controllers/posts_controller.rb
def index
scope = jsonapi_scope({})
posts = scope.resolve
puts posts # [#<Post:0x001>, #<Post:0x002>, ...]
render_jsonapi(posts, scope: false)
end
If we found ourselves typing similar Resource
code - always merging in
the same paramters to the hash - we’d probably want to package all this
up into an
Adapter.