graphql_controller.rb 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class GraphqlController < ApplicationController
  3. # Handled in the GraphQL processing, not on controller level.
  4. skip_before_action :verify_csrf_token
  5. prepend_before_action lambda {
  6. begin
  7. authentication_check_only
  8. rescue Exceptions::Forbidden
  9. # Don't throw if the user is not authenticated. Just continue without a current_user.
  10. end
  11. }
  12. def execute
  13. if params[:_json]
  14. return render json: multiplex
  15. end
  16. render json: single_query
  17. rescue => e
  18. raise e if !Rails.env.development?
  19. handle_error_in_development(e)
  20. end
  21. private
  22. def multiplex
  23. queries = params[:_json].map do |param|
  24. {
  25. query: param[:query],
  26. operation_name: param[:operationName],
  27. variables: prepare_variables(param[:variables]),
  28. context: context
  29. }
  30. end
  31. Gql::ZammadSchema.multiplex(queries)
  32. end
  33. def single_query
  34. query = params[:query]
  35. variables = prepare_variables(params[:variables])
  36. operation_name = params[:operation_name]
  37. Gql::ZammadSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
  38. end
  39. def context
  40. # context must be kept in sync with GraphqlChannel!
  41. {
  42. sid: session.id,
  43. current_user: current_user,
  44. current_user_id: current_user&.id,
  45. # :controller is used by login/logout mutations and MUST NOT be used otherwise.
  46. controller: self,
  47. }
  48. end
  49. # Handle variables in form data, JSON body, or a blank value
  50. def prepare_variables(variables_param)
  51. case variables_param
  52. when String
  53. if variables_param.present?
  54. JSON.parse(variables_param) || {}
  55. else
  56. {}
  57. end
  58. when Hash
  59. variables_param
  60. when ActionController::Parameters
  61. variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
  62. when nil
  63. {}
  64. else
  65. raise ArgumentError, "Unexpected parameter: #{variables_param}"
  66. end
  67. end
  68. def handle_error_in_development(e)
  69. logger.error e.message
  70. logger.error e.backtrace.join("\n")
  71. render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: :internal_server_error
  72. end
  73. end