0

I'm new to graphql-ruby and am running into a problem querying camel-cased data that is being served from an existing application. I've tried to search for some answers in the graphql-ruby tracker but most of them reference mutations, which I'm having trouble applying in the other direction.

Most of the data in the app is served snake-cased and that is working fine. But, there are some areas in which we send camel-cased data because of some use-case that existed long before I took on this project.

The resolver works correctly when I transform the data to snake-case but this seems like such a foreseeable situation that I'm guessing there is a solution somewhere that I'm not seeing.

Here's the code:

./graphql/types/user_notification_type.rb

module Types
  class UserNotificationType < Types::BaseObject
    field :base_type, String, null: true # I've tried changing this to :baseType to no avail
    field :action_type, String, null: true
  end
end

./app/graphql/types/query_type.rb

module Types
  class QueryType < Types::BaseObject
    field :notifications,
          [Types::UserNotificationType]
          null: true
          description: An array of user notifications

    # This doesn't work
    def notifications
      current_person_id = context[:current_person].id
      notifications = Resolvers::NotificationsResolver.new(current_person_id).notifications
 
      notifications
    end

    # But this works
    def notifications
      current_person_id = context[:current_person].id
      notifications = Resolvers::NotificationsResolver.new(current_person_id).notifications
 
      camel_case = notifications.dig(:alerts).map do |alert|   
        alert.transform_keys { |key| key.to_s.underscore }
      end
     
      camel_case
    end
  end
end

In this case, Resolvers::NotificationsResolver.new(current_person_id).notifications returns an array that looks like:

[
  {
    baseType: "some string"
    actionPath: "some string"

  }
]

The case that does not work returns null for each field. The case that works returns the correct value. But I'd rather not have to run these transformations for each of these cases.

What is the best way to tell graphql-ruby that it will be served camel-cased data and to serve that through a query properly?

Thanks in advance for any help!

wheresmyspaceship
  • 870
  • 2
  • 12
  • 19

1 Answers1

1

From GraphQL Ruby documentation [ 1 , 2 ]:

Field and argument names should be underscored as a convention. They will be converted to camelCase in the underlying GraphQL type and be camelCase in the schema itself.

Arguments that are snake_cased will be camelized in the GraphQL schema. Using the example of:

field :posts, [PostType], null: false do
  argument :start_year, Int, required: true
end

The corresponding GraphQL query will look like:

{
  posts(startYear: 2018) {
    id
  }
}

To disable auto-camelization, pass camelize: false to the argument method.

field :posts, [PostType], null: false do
  argument :start_year, Int, required: true, camelize: false
end

Furthermore, if your argument is already camelCased, then it will remain camelized in the GraphQL schema. However, the argument will be converted to snake_case when it is passed to the resolver method:

field :posts, [PostType], null: false do
  argument :startYear, Int, required: true
end

def posts(start_year:)
  # ...
end
mechnicov
  • 12,025
  • 4
  • 33
  • 56
  • This doesn't seem to work for the field itself though. I've tried `field: baseType` and `field: base_type` with and without the camelize: true/false and none of those seem to work – wheresmyspaceship Apr 02 '21 at 13:33
  • Field names basically are converted to camelCase – mechnicov Apr 02 '21 at 13:43
  • I'm sorry. Maybe I'm not explaining myself correctly. I'm specifically asking about when the data being queried is in camelCase. Graphql is returning `null` for those values unless I manually transform them to underscore first. So yes, `some_data` => `someData` works. But `someData` => `someData` is not working unless I manually transform it like `someData` => `some_data` => `someData` – wheresmyspaceship Apr 02 '21 at 14:05