Namespaces allow you to run multiple GraphQL schemas in the same Rails application. Each schema can have its own set of queries, mutations, and subscriptions while sharing common types and components.
# config/initializers/graphql.rbRails.application.config.after_initialize do GraphQL.type_map.associate(:admin, GraphQL::Admin) GraphQL.type_map.associate(:client, GraphQL::Client)end
Now all types under GraphQL::Admin automatically get the :admin namespace:
module GraphQL module Admin class UserType < Rails::GraphQL::Type::Object # Automatically has namespace :admin field :internal_notes, :string end endend
# app/graphql/types/user_type.rbmodule GraphQL class UserType < Rails::GraphQL::Type::Object namespace :base # Available to all schemas field :id, :id, null: false field :name, :string, null: false field :email, :string, null: false endend# app/graphql/sources/user_source.rbmodule GraphQL class UserSource < Rails::GraphQL::Source::ActiveRecordSource namespace :base assigned_to User endend
# app/graphql/client/client_schema.rbmodule GraphQL module Client class ClientSchema < Rails::GraphQL::Schema namespace :client, GraphQL::Client end endend# app/graphql/client/types/public_user_type.rbmodule GraphQL module Client class PublicUserType < UserType # Only exposes safe fields for public API field :avatar_url, :string field :bio, :string end endend# app/graphql/client/queries/me_query.rbmodule GraphQL module Client class MeQuery < Rails::GraphQL::Type::Object field :me, PublicUserType do authorize! { context[:current_user].present? } end def me context[:current_user] end end endend
module GraphQL class BaseType < Rails::GraphQL::Type::Object namespace :admin, :client end class UserType < BaseType # Inherits [:admin, :client] namespaces end class PrivateType < BaseType set_namespace :admin # Replaces inherited namespaces # Now only has [:admin] endend
Sources automatically attach to schemas in their namespaces:
module GraphQL class UserSource < Rails::GraphQL::Source::ActiveRecordSource namespace :admin, :client # Fields available in both AdminSchema and ClientSchema end class AuditLogSource < Rails::GraphQL::Source::ActiveRecordSource set_namespace :admin # Fields only in AdminSchema endend
Types without explicit namespaces default to :base
Shared components should use :base
module GraphQL # Implicitly has :base namespace class SharedType < Rails::GraphQL::Type::Object field :id, :id, null: false end # Explicitly set to :base class CommonType < Rails::GraphQL::Type::Object namespace :base field :created_at, :date_time endend
# Get component's namespacesUserType.namespaces # => [:admin, :client]# Find schemas with a namespaceRails::GraphQL::Schema.find(:admin) # => AdminSchema# Check if type exists in namespaceGraphQL.type_map.fetch('User', namespaces: :admin) # => UserType or nil
RSpec.describe 'Admin Schema' do let(:schema) { GraphQL::AdminSchema } it 'includes admin-only types' do expect(schema.types).to include('AdminUser') end it 'excludes client-only types' do expect(schema.types).not_to include('PublicProfile') end it 'includes shared types' do expect(schema.types).to include('User') endendRSpec.describe GraphQL::UserType do it 'belongs to correct namespaces' do expect(described_class.namespaces).to include(:admin, :client) endend