Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dox

Package Overview
Dependencies
Maintainers
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dox

  • 2.4.0
  • Rubygems
  • Socket score

Version published
Maintainers
2
Created
Source

Build Status Code Climate Test Coverage

Dox

Automate your documentation writing process! Dox generates API documentation from Rspec controller/request specs in a Rails application. It formats the tests output in the OpenApi format. Use the ReDoc renderer for generating and displaying the documentation as HTML.

Here's a demo app.

Installation

Add this line to your application's Gemfile:

group :test do
  gem 'dox', require: false
end

And then execute:

$ bundle

Or install it yourself as:

$ gem install dox

Usage

Require it

Require Dox in the rails_helper:

require 'dox'

Configure it

Set these optional options in the rails_helper:

OptionValueDescription
descriptions_locationPathname instance or fullpath string (can be an array)Folder containing markdown descriptions of resources.
schema_request_folder_pathPathname instance or fullpath stringFolder with request schemas of resources.
schema_response_folder_pathPathname instance or fullpath stringFolder with response schemas of resources.
schema_response_fail_file_pathPathname instance or fullpath stringJson file that contains the default schema of a failed response.
openapi_versionstringOpenapi version (default: '3.0.0' )
api_versionstringApi Version (default: '1.0')
titlestringDocumentation title (default: 'API Documentation')
header_descriptionPathname instance or stringDescription (header) of the documentation (default: ''). If pathname ends with .md, the file is looked in descriptions_location folder
headers_whitelistArray of headers (strings)Requests and responses will by default list only Content-Type header. To list other http headers, you must whitelist them.

Example:

Dox.configure do |config|
  config.descriptions_location  = Rails.root.join('spec/docs/v1/descriptions')
  config.schema_request_folder_path = Rails.root.join('spec/docs/v1/schemas')
  config.schema_response_folder_path = Rails.root.join('spec/support/v1/schemas')
  config.schema_response_fail_file_path = Rails.root.join('spec/support/v1/schemas/error.json')
  config.headers_whitelist = ['Accept', 'X-Auth-Token']
  config.title = 'API'
  config.api_version = '2.0'
  config.header_description = 'api_description.md'
end

Basic example

Define a descriptor module for a resource using Dox DSL:

module Docs
  module V1
    module Bids
      extend Dox::DSL::Syntax

      # define common resource data for each action
      document :api do
        resource 'Bids' do
          group 'Bids'
          desc 'bids.md'
        end
      end

      # define data for specific action
      document :index do
        action 'Get bids'
      end
    end
  end
end

You can define the descriptors for example in specs/docs folder, just make sure you load them in the rails_helper.rb:

Dir[Rails.root.join('spec/docs/**/*.rb')].each { |f| require f }

Include the descriptor modules in a controller and tag the specs you want to document with dox:

describe Api::V1::BidsController, type: :controller do
  # include resource module
  include Docs::V1::Bids::Api

  describe 'GET #index' do
    # include action module
    include Docs::V1::Bids::Index

    it 'returns a list of bids', :dox do
      get :index
      expect(response).to have_http_status(:ok)
    end
  end
end

And generate the documentation.

Advanced options

Before running into any more details, here's roughly how the generated OpenApi document is structured:

  • openapi
  • info
  • paths
    • action 1
      • tag1
      • example 1
      • example 2
    • action 2
      • tag2
      • example 3
  • x-tagGroups - tags1 - tag 1 - tag 2 - tags2 - tag 3 - tag 4
  • tags
    • tag1
    • tag2

OpenApi and info are defined in a json file as mentioned before. Examples are concrete test examples (you can have multiple examples for both happy and fail paths). They are completely automatically generated from the request/response objects. And you can customize the following in the descriptors:

  • x-tagGroup (resourceGroup)
  • tag (resource)
  • action
  • example
ResourceGroup

ResourceGroup contains related resources and is defined with:

  • name (required)
  • desc (optional, inline string or relative filepath)

Example:

document :bids_group do
  group 'Bids' do
    desc 'Here are all bid related resources'
  end
end

You can omit defining the resource group, if you don't have any description for it. Related resources will be linked in a group by the group option at the resource definition.

Resource

Resource contains actions and is defined with:

  • name (required)
  • group (required; to associate it with the related group)
  • desc (optional; inline string or relative filepath)

Example:

document :bids do
  resource 'Bids' do
    group 'Bids'
    desc 'bids/bids.md'
  end
end

Usually you'll want to define resourceGroup and resource together, so you don't have to include 2 modules with common data per spec file:

document :bids_common do
  group 'Bids' do
    desc 'Here are all bid related resources'
  end

  resource 'Bids' do
    group 'Bids'
    desc 'bids/bids.md'
  end
end
Action

Action contains examples and is defined with:

  • name (required)
  • path* (optional)
  • verb* (optional)
  • params (optional; depricated)
  • query_params (optional; more info)
  • desc (optional; inline string or relative filepath)
  • request_schema (optional; inline string or relative filepath)
  • response_schema_success (optional; inline string or relative filepath)
  • response_schema_fail (optional; inline string or relative filepath)

* these optional attributes are guessed (if not defined) from the request object of the test example and you can override them.

Example:

show_params = { id: { type: :number, required: :required, value: 1, description: 'bid id' } }
query_params = [ {
  "in": "query",
  "name": "filter",
  "required": false,
  "style": "deepObject",
  "explode": true,
  "schema": {
    "type": "object",
    "required": ["updated_at_gt"],
    "example": {
      "updated_at_gt": "2018-02-03 10:30:00"
    },
    "properties": {
      "updated_at_gt": {
        "type": "string",
        "title": "date"
      }
    }
  }
]

document :action do
  action 'Get bid' do
    path '/bids/{id}'
    verb 'GET'
    params show_params
    query_params query_params
    desc 'Some description for get bid action'
    request_schema 'namespace/bids'
    response_schema_success 'namespace/bids_s'
    response_schema_fail 'namespace/bids_f'
  end
end

Generate documentation

Documentation is generated in 2 steps:

  1. generate OpenApi json file: bundle exec rspec --tag apidoc -f Dox::Formatter --order defined --tag dox --out spec/api_doc/v1/schemas/docs.json

  2. render HTML with Redoc: redoc-cli bundle -o public/api/docs/v2/docs.html spec/api_doc/v1/schemas/docs.json

Use rake tasks

It's recommendable to write a few rake tasks to make things easier. Here's an example:

namespace :dox do
  desc 'Generate API documentation markdown'

  task :json, [:version, :docs_path, :host] => :environment do |_, args|
    require 'rspec/core/rake_task'
    version = args[:version] || :v1

    RSpec::Core::RakeTask.new(:api_spec) do |t|
      t.pattern = "spec/requests/api/#{version}"
      t.rspec_opts =
        "-f Dox::Formatter --tag dox --order defined --out spec/docs/#{version}/apispec.json"
    end

    Rake::Task['api_spec'].invoke
  end

  task :html, [:version, :docs_path, :host] => :json do |_, args|
    version = args[:version] || :v1
    docs_path = args[:docs_path] || "api/#{version}/docs"

    `yarn run redoc-cli bundle -o public/#{docs_path}/index.html spec/docs/#{version}/apispec.json`
  end

  task :open, [:version, :docs_path, :host] => :html do |_, args|
    version = args[:version] || :v1
    docs_path = args[:docs_path] || "api/#{version}/docs"

    `open public/#{docs_path}/index.html`
  end
end
Renderers

You can render the HTML yourself with ReDoc:

Common issues

You might experience some strange issues when generating the documentation. Here are a few examples of what we've encountered so far.

Uninitialized constant errors

There seems to be a problem with rspec-rails versions 3.7 and later not automatically requiring the project's rails_helper.rb when run with the --format flag.

To fix this issue, generate your documentation with --require rails_helper:

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/infinum/dox. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Credits

Dox is maintained and sponsored by Infinum.

Infinum

License

The gem is available as open source under the terms of the MIT License.

FAQs

Package last updated on 21 Nov 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc