Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 138 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ gem install graphql-docs

## Usage

GraphQLDocs provides two ways to serve your documentation:

1. **Static Site Generator (SSG)** - Pre-generate all HTML files (default)
2. **Rack Application** - Serve documentation dynamically on-demand

### Static Site Generation (SSG)

GraphQLDocs can be used as a Ruby library to build the documentation website. Using it as a Ruby library allows for more control and using every supported option. Here's an example:

```ruby
Expand Down Expand Up @@ -55,6 +62,110 @@ See all of the supported CLI options with:
graphql-docs -h
```

### Rack Application (Dynamic)

For more flexibility and control, you can serve documentation dynamically using the Rack application. This is useful for:

- Internal tools with frequently changing schemas
- Integration with existing Rails/Sinatra applications
- Adding authentication/authorization middleware
- Dynamic schema loading from databases or APIs

**Requirements**: The Rack application feature requires the `rack` gem (version 2.x or 3.x). Add it to your Gemfile:

```ruby
gem 'rack', '~> 3.0' # or '~> 2.0' for Rack 2.x
```

The gem is compatible with both Rack 2.x and 3.x, so you can use whichever version your application requires.

#### Standalone Rack App

Create a `config.ru` file:

```ruby
require 'graphql-docs'

schema = File.read('schema.graphql')

app = GraphQLDocs::App.new(
schema: schema,
options: {
base_url: '',
use_default_styles: true,
cache: true # Enable page caching
}
)

run app
```

Then run with:

```console
rackup config.ru
```

Visit `http://localhost:9292` to view your docs.

#### Mounting in Rails

```ruby
# config/routes.rb
require 'graphql-docs'

Rails.application.routes.draw do
mount GraphQLDocs::App.new(schema: MyGraphQLSchema) => '/docs'
end
```

#### Mounting in Sinatra

```ruby
require 'sinatra'
require 'graphql-docs'

schema = File.read('schema.graphql')
docs_app = GraphQLDocs::App.new(schema: schema)

map '/docs' do
run docs_app
end

map '/' do
run Sinatra::Application
end
```

#### Rack App Features

- **On-demand generation** - Pages are generated when requested
- **Built-in caching** - Generated pages are cached in memory (disable with `cache: false`)
- **Schema reloading** - Update schema without restarting server:

```ruby
app = GraphQLDocs::App.new(schema: schema)

# Later, reload with new schema
new_schema = File.read('updated_schema.graphql')
app.reload_schema!(new_schema)
```

- **Asset serving** - CSS, fonts, and images served automatically
- **Error handling** - Friendly error pages for missing types

#### SSG vs Rack Comparison

| Feature | SSG | Rack App |
|---------|-----|----------|
| Setup complexity | Low | Medium |
| First page load | Instant | Fast (with caching) |
| Schema updates | Manual rebuild | Automatic/reload |
| Hosting | Any static host | Requires Ruby server |
| Memory usage | Minimal | Higher (cached pages) |
| Authentication | Separate layer | Built-in middleware |
| Best for | Public docs, open source | Internal tools, dynamic schemas |

## Breakdown

There are several phases going on the single `GraphQLDocs.build` call:
Expand Down Expand Up @@ -398,20 +509,42 @@ an interactive prompt that will allow you to experiment.

## Sample Site

Clone this repository and run:
Clone this repository and try out both modes:

```
### Static Site Generation

Generate the sample documentation to the `output` directory:

```console
bin/rake sample:generate
```

to see some sample output in the `output` dir.
Then boot up a server to view the pre-generated files:

```console
bin/rake sample:serve
```

Visit `http://localhost:5050` to view the static documentation.

Boot up a server to view it:
### Rack Application (Dynamic)

Run the sample docs as a dynamic Rack application:

```console
bin/rake sample:rack
```
bin/rake sample:serve

Or use the config.ru directly:

```console
rackup config.ru
```

Visit `http://localhost:9292` to view the documentation served dynamically.

**Key Difference**: The SSG version pre-generates all pages (faster initial load, no runtime cost), while the Rack version generates pages on-demand (better for dynamic schemas, easier integration).

## Credits

Originally built by [gjtorikian](https://github.com/gjtorikian). Actively maintained by [brettchalupa](https://github.com/brettchalupa).
30 changes: 30 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,34 @@ namespace :sample do
server.start
end
task server: :serve

desc 'Run the sample docs as a Rack application (dynamic, on-demand generation)'
task :rack do
require 'rack'
require 'graphql-docs'

schema_path = File.join(File.dirname(__FILE__), 'test', 'graphql-docs', 'fixtures', 'gh-schema.graphql')
schema = File.read(schema_path)

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

PORT = ENV.fetch('PORT', '9292')
puts "Starting Rack server in dynamic mode (on-demand generation)"
puts "Navigate to http://localhost:#{PORT} to view the sample docs"
puts "Press Ctrl+C to stop"
puts ""
puts "NOTE: This serves documentation dynamically - pages are generated on request"
puts " Compare with 'rake sample:serve' which serves pre-generated static files"
puts ""

# Use rackup for Rack 3.x compatibility
sh "rackup config.ru -p #{PORT}"
end
end
44 changes: 44 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

# Rack configuration file for running GraphQL Docs as a web server
#
# This demonstrates using GraphQLDocs as a Rack application that serves
# documentation dynamically on-demand instead of pre-generating static files.
#
# Run with: rackup config.ru
# Or with specific port: rackup config.ru -p 9292

require_relative 'lib/graphql-docs'

# Load the sample GraphQL schema
schema_path = File.join(__dir__, 'test', 'graphql-docs', 'fixtures', 'gh-schema.graphql')

unless File.exist?(schema_path)
puts "Error: Sample schema not found at #{schema_path}"
puts "Please ensure the schema file exists before starting the server."
exit 1
end

schema = File.read(schema_path)

# Create the Rack app
app = GraphQLDocs::App.new(
schema: schema,
options: {
base_url: '',
use_default_styles: true,
cache: true
}
)

# Log requests in development
use Rack::CommonLogger

# Add reloader for development (optional, requires 'rack' gem)
if ENV['RACK_ENV'] != 'production'
puts "Running in development mode"
puts "Visit http://localhost:9292 to view the documentation"
puts "Press Ctrl+C to stop the server"
end

run app
8 changes: 8 additions & 0 deletions graphql-docs.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,17 @@ Gem::Specification.new do |spec|
spec.add_dependency 'ostruct', '~> 0.6'
spec.add_dependency 'logger', '~> 1.6'

# rack application support (optional, only needed for GraphQLDocs::App)
# Users can install rack separately if they want to use the Rack app feature:
# gem 'rack', '~> 2.0' or gem 'rack', '~> 3.0'
# The gem works with both Rack 2.x and 3.x

spec.add_development_dependency 'html-proofer', '~> 3.4'
spec.add_development_dependency 'minitest', '~> 5.24'
spec.add_development_dependency 'minitest-focus', '~> 1.1'
spec.add_development_dependency 'rack', '>= 2.0', '< 4'
spec.add_development_dependency 'rack-test', '~> 2.0'
spec.add_development_dependency 'rackup', '~> 2.0'
spec.add_development_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rubocop', '~> 1.37'
spec.add_development_dependency 'rubocop-performance', '~> 1.15'
Expand Down
7 changes: 7 additions & 0 deletions lib/graphql-docs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
require 'graphql-docs/parser'
require 'graphql-docs/version'

# Lazy-load the Rack app - only loads if Rack is available
begin
require 'graphql-docs/app' if defined?(Rack)
rescue LoadError
# Rack not available, App class won't be loaded
end

# GraphQLDocs is a library for generating beautiful HTML documentation from GraphQL schemas.
# It parses GraphQL schema files or schema objects and generates a complete documentation website
# with customizable templates and styling.
Expand Down
Loading