Advice for Modularizing a GraphQL API in a Rails Monolith

This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.

Message originally sent by slack user U71OA7MT4IW

Hello! :wave:

I’m about to embark on a modularization project for a Rails monolith we have at PGA of America:man-golfing:. Very grateful for the resources that Gusto and Shopify have provided.

Does anyone have experience and can offer guidance for modularization of a GraphQL API service? Would you have a separate component for the GraphQL layer that depends on several domain-specific components? Or is there a way for each domain-specific component to expose GraphQL bits as part of its public API?

ooo :slightly_smiling_face: our first GraphQL question!

:wave:

At gusto we have weighed these various options. I am curious if others have experience, but in general, this is wonderful bundle of tradeoffs the decision of which depends on a lot of factors. If you have the capability to experiment (for a small part of the graph) with each option, you’ll learn a ton.

And if you have fairly large sized components, individual subgraphs per component are an interesting option too

We used modular approach for GraphQL via GraphQL Ruby interfaces. Here is a simplified ApplicationSchema class demonstrating the composition:

class ApplicationSchema < Common::GraphQL::Schema
  class MeRoot < Common::GraphQL::Object
    implements ConnectBy::Types::MeInterface
    implements MeetBy::Types::MeInterface
  end

  class QueryRoot < Common::GraphQL::Object
    implements ConnectBy::QueryInterface
    implements PerksBy::QueryInterface
    implements ChatBy::QueryInterface
    implements MeetBy::QueryInterface

    field :me, MeRoot, "Current user's sub-graph", null: false

    def me
      current_user
    end
  end

  class MutationRoot < GraphQL::Schema::Object
    implements ConnectBy::Mutations::MutationInterface
    implements ChatBy::Mutations::MutationInterface
    implements MeetBy::Mutations::MutationInterface
  end

  query QueryRoot
  mutation MutationRoot
end

(I don’t remember if we had any extensions though)

Another approach we considered for later projects is to follow GraphQL Federation principles (and even re-use federation interfaces/tools but using a virtual networking, i.e., in-process communication).