The easiest way to start from scratch is to use the application
template:
$ rails new blog --api -m https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb
Alternatively, download and point to the template locally:
$ curl -O https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb
$ rails new blog --api -m all.rb
Run git diff
to see the changes to a blank Rails app.
This process is straightforward; you can add Graphiti to an existing
Rails app alongside JBuilder or ActiveModelSerializers .
Start with gems:
# The only strictly-required gem
gem 'graphiti'
# For automatic ActiveRecord pagination
gem 'kaminari'
# Test-specific gems
group :development , :test do
gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'faker'
gem 'graphiti_spec_helpers'
end
group :test do
gem 'database_cleaner'
end
You’ll be up-and-running at this point. Verify with a simple standalone
Resource:
# Assuming you already have a Post ActiveRecord Model
class PostResource < Graphiti :: Resource
self . adapter = Graphiti :: Adapters :: ActiveRecord
attribute :title , :string
end
PostResource . all . data # => [#<Post>, #<Post>, ...]
Now we just need to integrate with Rails endpoints (to give us things
like #context ):
# app/controllers/application_controller.rb
class ApplicationController < ActionController :: Base
include Graphiti :: Rails
end
And wire-up our error-handling:
# app/controllers/application_controller.rb
# When #show action does not find record, return 404
register_exception Graphiti :: Errors :: RecordNotFound ,
status: 404
rescue_from Exception do | e |
handle_exception ( e )
end
That’s it for the basics. You may have issues with generators
conflicting with your existing application structure - but you can
always write files manually or submit an issue .
Graphiti supports JSONAPI, simple JSON, and XML. You can do this
manually when inheriting from ActionController::Base
def index
posts = PostResource . all ( params )
respond_to do | format |
format . json { render ( json: posts ) }
format . jsonapi { render ( jsonapi: posts ) }
format . xml { render ( xml: posts ) }
end
end
But we can inherit from ActionController::API
while avoiding this
boilerplate with with the Responders gem:
def index
posts = PostResource . all ( params )
respond_with ( posts )
end
To get this functionality:
# Gemfile
gem 'responders'
# app/controllers/application_controller.rb
include Graphiti :: Responders
Note: Persistence operations only support JSONAPI format, so you’ll
still use render jsonapi:
and render jsonapi_errors:
for those.
The .graphiticfg.yml
file lives in the root directory of your
application. It holds configuration we need to reuse across a variety of
contexts (primarily generates and rake tasks). If you use our template to create your application, it’s created for you.
Primarily this is used to hold your “API namespace”:
---
namespace: /my_api/v1
If this file doesn’t exist you may get unexpected errors - make sure to
create it!
To add our Integration Tests :
# Gemfile
group :development , :test do
gem 'graphiti_spec_helpers'
gem 'factory_bot_rails'
gem 'rspec_rails'
gem 'faker'
end
group :test do
gem 'database_cleaner'
end
Bootstrap RSpec if you haven’t already:
$ bin/rails g rspec:install
Add some RSpec configuration:
require 'graphiti_spec_helpers/rspec'
RSpec . configure do | config |
config . include FactoryBot :: Syntax :: Methods
config . include GraphitiSpecHelpers :: RSpec
config . include GraphitiSpecHelpers :: Sugar
# Raise errors during tests by default
config . before :each do
GraphitiErrors . disable!
end
# Clean your DB between test runs
config . before ( :suite ) do
DatabaseCleaner . strategy = :transaction
DatabaseCleaner . clean_with ( :truncation )
end
config . around ( :each ) do | example |
begin
DatabaseCleaner . cleaning do
example . run
end
ensure
DatabaseCleaner . clean
end
end
end
By default, we use Kaminari for
ActiveRecord pagination. If you prefer [will_paginate] (or anything
else):
# app/resources/application_resource.rb
paginate do | scope , current_page , per_page |
scope . paginate ( page: current_page , per_page: per_page )
end
You can use Graphiti in any plain .rb
file. To see this in action,
check out the Plain Ruby Sample App .