Usage Without ActiveRecord: ElasticSearch
Though we’ll be hitting elasticsearch in this example, remember that this is just an HTTP API underneath the hood. The same pattern applies to a variety of use cases.
First we need a Client for elasticsearch
. Though you can feel free
to use a variety of clients, this example will use trample.
Also keep in mind, we’ll be showing a one-off customization here. You probably want to extract this code into an Adapter if this is going to become a core component of your application.
Pre-JSONAPI Setup
Start by installing trample:
Tell searchkick that we want to
index Employee
s and Position
s:
Define our search classes. These tell trample the configuration of the search:
Finally, seed some data:
JSONAPI Integration
In our controller, we need to pass a base scope. In ActiveRecord
examples, we’d pass an ActiveRecord::Relation
(e.g. Post.all
). Let’s pass an instance
of Trample::Search
instead.
Since we are now passing a non-default base scope, we need to tell our
Resource
how to query and resolve this new scope. Start by switching to
the pass-through adapter, and resolve using trample
’s query API:
You can now hit http://localhost:3000/api/v1/employees
- the exact
same payload is coming back, but is now sourced from elasticsearch
!
Let’s add a prefix filter:
Hit http://localhost:3000/api/v1/employees?filter[first_name]=hom
.
You’re now successfully querying the elasticsearch
index.
If we want sorting and pagination, we need to tell the Resource
how to deal with that, too:
View the Resource and Adapter documentation for additional overrides, like statistics.
The last step is adding the positions
association. If we want
has_many
-style macros we need to create an
Adapter, but for now
let’s simply use the lower-level allow_sideload DSL. We need to define
two functions: how to build a scope for the association, and how to
associate the resulting objects:
Convert the PositionResource
to use elasticsearch
, just like we did
for Employee
:
Create the SerializablePosition
class:
We can now sideload positions
- check out the results at
http://localhost:3000/api/v1/employees?include=positions
. We’re
fetching employees and their corresponding positions
in a single
request, via elasticsearch
. Any filters/changes/default sort/etc that
apply to PositionResource
can be re-used at this endpoint.
If this was a one-off section of our application, we can call this good
enough and move on. But as we continue to use this pattern, it’s going
to get monotonous writing the same filter overrides, allow_sideload
wiring code, etc. To DRY up this code, we can package our changes into
an Adapter.