Class: GraphQLDocs::App

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/graphql-docs/app.rb

Overview

Rack application for serving GraphQL documentation on-demand.

This provides an alternative to the static site generator approach, allowing documentation to be served dynamically from a Rack-compatible web server. Pages are generated on-demand and can be cached for performance.

Thread Safety: This application is designed to be thread-safe for use with multi-threaded web servers like Puma or Falcon. Thread safety is achieved through:

  1. Immutable core state: @parsed_schema, @base_options, and @renderer are set once during initialization and never mutated.
  2. Temporary renderers: When YAML frontmatter is present, a new temporary renderer is created per-request instead of mutating shared state.
  3. Cache thread-safety: The @cache hash may require external synchronization in highly concurrent scenarios (consider using a thread-safe cache adapter).

Examples:

Standalone usage

app = GraphQLDocs::App.new(
  schema: 'type Query { hello: String }',
  options: { base_url: '' }
)
run app

Mount in Rails

mount GraphQLDocs::App.new(schema: MySchema) => '/docs'

With caching

app = GraphQLDocs::App.new(
  schema: schema_string,
  options: { cache: true }
)

Constant Summary

Constants included from Helpers

Helpers::SLUGIFY_PRETTY_REGEXP

Instance Attribute Summary collapse

Attributes included from Helpers

#templates

Instance Method Summary collapse

Methods included from Helpers

#graphql_directive_types, #graphql_enum_types, #graphql_input_object_types, #graphql_interface_types, #graphql_mutation_types, #graphql_object_types, #graphql_operation_types, #graphql_query_types, #graphql_root_types, #graphql_scalar_types, #graphql_union_types, #include, #markdownify, #slugify, #split_into_metadata_and_contents, #yaml?, #yaml_split

Constructor Details

#initialize(schema: nil, filename: nil, options: {}) ⇒ App

Initializes a new Rack app instance.

Parameters:

  • schema (String, GraphQL::Schema) (defaults to: nil)

    GraphQL schema as IDL string or schema class

  • filename (String, nil) (defaults to: nil)

    Path to GraphQL schema file (alternative to schema param)

  • options (Hash) (defaults to: {})

    Configuration options

Options Hash (options:):

  • :base_url (String) — default: ''

    Base URL prefix for all routes

  • :cache (Boolean) — default: true

    Enable page caching

  • :use_default_styles (Boolean) — default: true

    Serve default CSS

  • :templates (Hash)

    Custom template paths

  • :renderer (Class)

    Custom renderer class

Raises:

  • (ArgumentError)

    If neither schema nor filename is provided



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/graphql-docs/app.rb', line 78

def initialize(schema: nil, filename: nil, options: {})
  raise ArgumentError, "Must provide either schema or filename" if schema.nil? && filename.nil?

  @base_options = Configuration::GRAPHQLDOCS_DEFAULTS.merge(options).freeze
  @options = @base_options.dup

  # Load schema from file if filename provided
  if filename
    raise ArgumentError, "#{filename} does not exist!" unless File.exist?(filename)
    schema = File.read(filename)
  end

  # Parse schema once at initialization
  parser = Parser.new(schema, @options)
  @parsed_schema = parser.parse

  @renderer = @options[:renderer].new(@parsed_schema, @options)

  # Initialize cache
  @cache_enabled = @options.fetch(:cache, true)
  @cache = {} if @cache_enabled

  # Load templates
  load_templates

  # Pre-compile assets if using default styles
  compile_assets if @options[:use_default_styles]
end

Instance Attribute Details

#base_optionsObject (readonly)

Returns the value of attribute base_options.



64
65
66
# File 'lib/graphql-docs/app.rb', line 64

def base_options
  @base_options
end

#optionsObject (readonly)

Returns the value of attribute options.



60
61
62
# File 'lib/graphql-docs/app.rb', line 60

def options
  @options
end

#parsed_schemaObject (readonly)

Returns the value of attribute parsed_schema.



56
57
58
# File 'lib/graphql-docs/app.rb', line 56

def parsed_schema
  @parsed_schema
end

Instance Method Details

#call(env) ⇒ Array

Rack interface method.

Parameters:

  • env (Hash)

    Rack environment hash

Returns:

  • (Array)

    Rack response tuple [status, headers, body]



111
112
113
114
115
116
117
118
# File 'lib/graphql-docs/app.rb', line 111

def call(env)
  request = Rack::Request.new(env)
  path = clean_path(request.path_info)

  route(path)
rescue => e
  [500, {"content-type" => "text/html"}, [error_page(e)]]
end

#clear_cache!void

This method returns an undefined value.

Clears the page cache.



123
124
125
# File 'lib/graphql-docs/app.rb', line 123

def clear_cache!
  @cache&.clear
end

#reload_schema!(new_schema) ⇒ void

This method returns an undefined value.

Reloads the schema and clears cache.

Parameters:

  • new_schema (String, GraphQL::Schema)

    New schema to parse



131
132
133
134
135
136
# File 'lib/graphql-docs/app.rb', line 131

def reload_schema!(new_schema)
  parser = Parser.new(new_schema, @options)
  @parsed_schema = parser.parse
  @renderer = @options[:renderer].new(@parsed_schema, @options)
  clear_cache!
end