APIQL
Implementation of the API language similar to GraphQL for Ruby on Rails
Define your responder (requested methods):
class UserAPIQL < ::APIQL
def me
:show, ::User
current_user
end
def authenticate(email, password)
user = ::User.find_by(email)
user.authenticate(password)
user
end
def logout
current_user&.logout
:ok
end
end
In controller or Grape API endpoint, handler of POST /user method:
def user
schema = APIQL.cache(params)
UserAPIQL.new(self, :session, :current_user, :params).render(schema)
end
variables session, current_user and params will be stored into context you can use in presenters and handlers
Define presenters for your models:
class User < ApplicationRecord
class Entity < ::APIQL::Entity
attributes :full_name, :email, :token, :role, :roles
def token
object.token if object == current_user
end
end
has_many :roles
...
end
JS:
assets/javascripts/application.js:
//= require apiql
APIQL.endpoint = "/"
authenticate(email, password) {
let api = new APIQL("user")
api.call(`
logout()
authenticate(email,password) {
token
}
me {
email full_name role token
}
`, {
email: email,
password: password
})
.then(response => {
let user = response.me
})
}
logout() {
let api = new APIQL("user")
api.call(`
logout
`)
.then(response => {
})
}
You can use initializer like this for authorization using cancancan gem:
config/initializers/apiql.rb:
class APIQL
delegate :authorize!, to: :@context
class Context
def (*args)
ability.(*args)
end
private
def ability
@ability ||= ::Ability::Factory.build_ability_for(current_user)
end
end
end