1
votes

I'm trying to migrate from using a Rails REST API to using GraphQL. One of our REST endpoints that we're trying to replace uses a serializer. In that serializer, we return either a string or a boolean, depending on if the string is "true" or "false". I'm having trouble creating a graphql object that can handle this. I've tried creating a custom type, and a custom scalar to no avail. I'm trying to use rspec to test out the graphql query, but when I try using a custom scalar or custom type, i keep getting a runtime error that says: no implicit conversion of nil into String

The unhelpful part is I don't have a good way of debugging what is causing this error.

  1. is there an easy way to define a graphQL field that will return either a boolean or a string?
  2. does anyone have any suggestions on how to debug the error I'm getting via rspec? I've tried using byebug in different places, but the byebug statement is never getting hit.

Here's an example of a serializer I'm trying to convert to graphql

class ModelToSerialize < ActiveModel::Serializer
  attributes :id, :customization_key, :value
  # value is stored as a string in the relational database
  # customization_key is stored as an integer in the relational database  

  def value
    if object.customization_key == 1
      return true if object.value == true || object.value =~ /^(true|t|yes|y|1)$/i
      return false
    else
      object.value
    end
  end
end

Here's the GraphQL type that I tried to create:

module Types
  class ModelToSerializeType < Types::BaseObject
    field :id, Int, null: false
    field :value, String, null: false # this should return boolean OR string
    field :customization_key, Int, null: false, camelize: false
  end
end

The above doesn't work because I'm limiting the type to be String, but I want it to return either a boolean or a string. Even if I copy/paste the code from the serializer into the type definition, it will still only return a string

1
updated to include serializer code - Dennis
You have to provide a better code sample, showing what you have, what the error is, the stack trace for the error, what you've done to try to convert it, etc. Walk us through the problem. Don't give a generic problem description and say "I've tried to troubleshoot it but can't tell you how or where I'm stuck." - anothermh
It sounds like this might be a case for using a Union. graphql-ruby.org/type_definitions/unions.html - David Aldridge

1 Answers

0
votes

GraphQL is strongly typed. You cannot, by design, declare a field that might return multiple types. It's a bit of code smell to even do that in ActiveRecord, tbh.

Options I'd consider to deal with the setup as is:

  1. Just use the string; parse it into a boolean if needed on the front end.
  2. Expand value into two fields; one that is a bool and one that is a string. Declare both null: true and only give the appropriately-typed field a value. That way you can reuse the serializer in the back end, while the front-end only has to check which field has a non-null value.

    2a. Instead of a Boolean and a String field, you could use a value (String) and a type (String value, one of "Boolean" or "String") field. Same information, different way of encoding it.

I'm trying to think of a way to use Inline Fragments; I think it's doable but more trouble than it's worth.