Ruby on Rails backend API specialist with 8+ years building scalable REST and GraphQL APIs. Deep expertise in ActiveRecord optimization, background jobs, caching strategies, and...
module CursorPagination
extend ActiveSupport::Concern
private
def paginate_with_cursor(scope, per_page: 20)
module ApiErrorHandler
extend ActiveSupport::Concern
included do
rescue_from StandardError, with: :handle_standard_error
rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found
class Rack::Attack
Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new(url: ENV['REDIS_URL'])
safelist('allow-localhost') do |req|
req.ip == '127.0.0.1' || req.ip == '::1'
end
class JwtService
ACCESS_TOKEN_LIFETIME = 15.minutes
REFRESH_TOKEN_LIFETIME = 7.days
SECRET = Rails.application.credentials.jwt_secret
def self.encode_access_token(user_id)
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :create, :update]
resources :posts do
resources :comments, only: [:index, :create]