Sha256: c0afa79465833fc278cac8d627ee42c5719301c9ae76eab6ccdafd05c7c16ba0

Contents?: true

Size: 1.92 KB

Versions: 2

Compression:

Stored size: 1.92 KB

Contents

module Daidan
  class Application
    def initialize
      setup_zeitwerk
      super
    end

    def call(env)
      process_request(env)
    rescue JSON::ParserError
      handle_json_parse_error
    rescue StandardError => e
      handle_internal_server_error(e)
    end

    protected

    def process_request(env)
      req = Rack::Request.new(env)

      if req.post? && req.path == '/graphql'
        handle_graphql_request(req, env)
      else
        not_found_response
      end
    end

    def graphql_schema
      raise NotImplementedError, 'Subclasses must define `graphql_schema`'
    end

    def handle_json_parse_error
      [400, { 'content-type' => 'application/json' }, [{ error: 'Invalid JSON' }.to_json]]
    end

    def handle_internal_server_error(error)
      puts "Error processing request: #{error.message}"
      [500, { 'content-type' => 'application/json' }, [{ error: 'Internal Server Error' }.to_json]]
    end

    def not_found_response
      [404, { 'content-type' => 'text/plain' }, ['Not Found']]
    end

    def setup_zeitwerk
      app_root = Dir.pwd

      loader = Zeitwerk::Loader.new
      loader.push_dir(File.join(app_root, ''))
      loader.collapse(File.join(app_root, 'graphql'))
      loader.collapse(File.join(app_root, 'graphql', 'types'))
      loader.collapse(File.join(app_root, 'graphql', 'mutations'))
      loader.collapse(File.join(app_root, 'models'))
      loader.setup
    end

    private

    def handle_graphql_request(req, env)
      body = req.body.read
      params = body.empty? ? {} : JSON.parse(body)

      current_user = env['current_user_id'] ? User.find(id: env['current_user_id']) : nil

      result = graphql_schema.execute(
        params['query'],
        variables: params['variables'],
        context: { current_user: current_user },
        operation_name: params['operationName']
      )

      [200, { 'content-type' => 'application/json' }, [result.to_json]]
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
daidan-0.2.0 lib/daidan/config/application.rb
daidan-0.1.0 lib/daidan/config/application.rb