{"id":13878834,"url":"https://github.com/infinum/dox","last_synced_at":"2025-08-05T12:48:18.649Z","repository":{"id":43961950,"uuid":"60545890","full_name":"infinum/dox","owner":"infinum","description":"Automated API documentation from Rspec","archived":false,"fork":false,"pushed_at":"2024-12-11T12:43:18.000Z","size":269,"stargazers_count":239,"open_issues_count":8,"forks_count":22,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-07-27T14:47:17.306Z","etag":null,"topics":["open-source","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infinum.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-06T17:07:25.000Z","updated_at":"2025-01-23T12:01:05.000Z","dependencies_parsed_at":"2024-06-18T22:56:59.797Z","dependency_job_id":"6a3da144-7f99-4488-9fb1-aab3b6fa5310","html_url":"https://github.com/infinum/dox","commit_stats":{"total_commits":165,"total_committers":13,"mean_commits":"12.692307692307692","dds":0.2848484848484848,"last_synced_commit":"1b5f8e9b431b83a2ea320eaf83cd01fb66b71a6a"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/infinum/dox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fdox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fdox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fdox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fdox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infinum","download_url":"https://codeload.github.com/infinum/dox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinum%2Fdox/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268696676,"owners_count":24292372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["open-source","ruby"],"created_at":"2024-08-06T08:02:01.477Z","updated_at":"2025-08-05T12:48:18.595Z","avatar_url":"https://github.com/infinum.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/infinum/dox.svg?branch=master)](https://travis-ci.org/infinum/dox)\n[![Code Climate](https://codeclimate.com/github/infinum/dox/badges/gpa.svg)](https://codeclimate.com/github/infinum/dox)\n[![Test Coverage](https://codeclimate.com/github/infinum/dox/badges/coverage.svg)](https://codeclimate.com/github/infinum/dox/coverage)\n\n# Dox\n\nAutomate 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](https://www.openapis.org/) format. Use the ReDoc renderer for generating and displaying the documentation as HTML.\n\nHere's a [demo app](https://github.com/infinum/dox-demo).\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngroup :test do\n  gem 'dox', require: false\nend\n```\n\nAnd then execute:\n\n```\n$ bundle\n```\n\nOr install it yourself as:\n\n```\n$ gem install dox\n```\n\n## Usage\n\n### Require it\n Require Dox in the rails_helper:\n\n ``` ruby\n require 'dox'\n ```\n\n### Configure it\nSet these optional options in the rails_helper:\n\n| Option | Value | Description |\n| -- | -- | -- |\n| descriptions_location | Pathname instance or fullpath string (can be an array) | Folder containing markdown descriptions of resources. |\n| schema_request_folder_path | Pathname instance or fullpath string | Folder with request schemas of resources. |\n| schema_response_folder_path | Pathname instance or fullpath string | Folder with response schemas of resources. |\n| schema_response_fail_file_path | Pathname instance or fullpath string | Json file that contains the default schema of a failed response. |\n| openapi_version | string | Openapi version (default: '3.0.0' ) |\n| api_version | string | Api Version (default: '1.0') |\n| title | string | Documentation title (default: 'API Documentation') |\n| header_description | Pathname instance or string | Description (header) of the documentation (default: ''). If pathname ends with `.md`, the file is looked in `descriptions_location` folder |\n| headers_whitelist | Array of headers (strings) | Requests and responses will by default list only `Content-Type` header. To list other http headers, you must whitelist them.|\n| check_file_presence_on_init | boolean | Option defaults to true. In case an .md file doesn't exist, dox won't wait for the specs to pass before attempting to print the documentation. It will raise an error early during resource initialization. If you're calling Dox.configure multiple times during the spec suite, you might want to set this to false. |\n\nExample:\n\n``` ruby\nDox.configure do |config|\n  config.descriptions_location  = Rails.root.join('spec/docs/v1/descriptions')\n  config.schema_request_folder_path = Rails.root.join('spec/docs/v1/schemas')\n  config.schema_response_folder_path = Rails.root.join('spec/support/v1/schemas')\n  config.schema_response_fail_file_path = Rails.root.join('spec/support/v1/schemas/error.json')\n  config.headers_whitelist = ['Accept', 'X-Auth-Token']\n  config.title = 'API'\n  config.api_version = '2.0'\n  config.header_description = 'api_description.md'\nend\n```\n\n### Basic example\n\nDefine a descriptor module for a resource using Dox DSL:\n\n``` ruby\nmodule Docs\n  module V1\n    module Bids\n      extend Dox::DSL::Syntax\n\n      # define common resource data for each action\n      document :api do\n        resource 'Bids' do\n          group 'Bids'\n          desc 'bids.md'\n        end\n      end\n\n      # define data for specific action\n      document :index do\n        action 'Get bids'\n      end\n    end\n  end\nend\n\n```\n\u003csmall\u003eYou can define the descriptors for example in specs/docs folder, just make sure you load them in the rails_helper.rb:\n\n``` ruby\nDir[Rails.root.join('spec/docs/**/*.rb')].each { |f| require f }\n```\n\u003c/small\u003e\n\nInclude the descriptor modules in a controller and tag the specs you want to document with **dox**:\n\n``` ruby\ndescribe Api::V1::BidsController, type: :controller do\n  # include resource module\n  include Docs::V1::Bids::Api\n\n  describe 'GET #index' do\n    # include action module\n    include Docs::V1::Bids::Index\n\n    it 'returns a list of bids', :dox do\n      get :index\n      expect(response).to have_http_status(:ok)\n    end\n  end\nend\n```\n\nAnd [generate the documentation](#generate-documentation).\n\n\n### Advanced options\n\nBefore running into any more details, here's roughly how the generated OpenApi document is structured:\n\n- openapi\n- info\n- paths\n  - action 1\n    - tag1\n    - example 1\n    - example 2\n  - action 2\n    - tag2\n    - example 3\n- x-tagGroups\n      - tags1\n        - tag 1\n        - tag 2\n      - tags2\n        - tag 3\n        - tag 4\n- tags\n  - tag1\n  - tag2\n\n\nOpenApi 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.\nAnd you can customize the following in the descriptors:\n\n- x-tagGroup (**resourceGroup**)\n- tag (**resource**)\n- action\n- example\n\n#### ResourceGroup\n\nResourceGroup contains related resources and is defined with:\n- **name** (required)\n- desc (optional, inline string or relative filepath)\n\nExample:\n``` ruby\ndocument :bids_group do\n  group 'Bids' do\n    desc 'Here are all bid related resources'\n  end\nend\n```\n\nYou 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.\n\n#### Resource\nResource contains actions and is defined with:\n- **name** (required)\n- **group** (required; to associate it with the related group)\n- desc (optional; inline string or relative filepath)\n\nExample:\n``` ruby\ndocument :bids do\n  resource 'Bids' do\n    group 'Bids'\n    desc 'bids/bids.md'\n  end\nend\n```\n\nUsually you'll want to define resourceGroup and resource together, so you don't have to include 2 modules with common data per spec file:\n\n``` ruby\ndocument :bids_common do\n  group 'Bids' do\n    desc 'Here are all bid related resources'\n  end\n\n  resource 'Bids' do\n    group 'Bids'\n    desc 'bids/bids.md'\n  end\nend\n```\n\n#### Action\nAction contains examples and is defined with:\n- **name** (required)\n- path* (optional)\n- verb* (optional)\n- params (optional; _depricated_)\n- query_params (optional; [more info](https://swagger.io/docs/specification/describing-parameters/#query-parameters))\n- desc (optional; inline string or relative filepath)\n- request_schema (optional; inline string or relative filepath)\n- response_schema_success (optional; inline string or relative filepath)\n- response_schema_fail (optional; inline string or relative filepath)\n\n\\* these optional attributes are guessed (if not defined) from the request object of the test example and you can override them.\n\nExample:\n\n``` ruby\nshow_params = { id: { type: :number, required: :required, value: 1, description: 'bid id' } }\nquery_params = [ {\n  \"in\": \"query\",\n  \"name\": \"filter\",\n  \"required\": false,\n  \"style\": \"deepObject\",\n  \"explode\": true,\n  \"schema\": {\n    \"type\": \"object\",\n    \"required\": [\"updated_at_gt\"],\n    \"example\": {\n      \"updated_at_gt\": \"2018-02-03 10:30:00\"\n    },\n    \"properties\": {\n      \"updated_at_gt\": {\n        \"type\": \"string\",\n        \"title\": \"date\"\n      }\n    }\n  }\n]\n\ndocument :action do\n  action 'Get bid' do\n    path '/bids/{id}'\n    verb 'GET'\n    params show_params\n    query_params query_params\n    desc 'Some description for get bid action'\n    request_schema 'namespace/bids'\n    response_schema_success 'namespace/bids_s'\n    response_schema_fail 'namespace/bids_f'\n  end\nend\n```\n\n### Generate documentation\nDocumentation is generated in 2 steps:\n\n1. generate OpenApi json file:\n```bundle exec rspec --tag apidoc -f Dox::Formatter --order defined --tag dox --out spec/api_doc/v1/schemas/docs.json```\n\n2. render HTML with Redoc:\n```redoc-cli bundle -o public/api/docs/v2/docs.html spec/api_doc/v1/schemas/docs.json```\n\n\n#### Use rake tasks\nIt's recommendable to write a few rake tasks to make things easier. Here's an example:\n\n```ruby\nnamespace :dox do\n  desc 'Generate API documentation markdown'\n\n  task :json, [:version, :docs_path, :host] =\u003e :environment do |_, args|\n    require 'rspec/core/rake_task'\n    version = args[:version] || :v1\n\n    RSpec::Core::RakeTask.new(:api_spec) do |t|\n      t.pattern = \"spec/requests/api/#{version}\"\n      t.rspec_opts =\n        \"-f Dox::Formatter --tag dox --order defined --out spec/docs/#{version}/apispec.json\"\n    end\n\n    Rake::Task['api_spec'].invoke\n  end\n\n  task :html, [:version, :docs_path, :host] =\u003e :json do |_, args|\n    version = args[:version] || :v1\n    docs_path = args[:docs_path] || \"api/#{version}/docs\"\n\n    `yarn run redoc-cli bundle -o public/#{docs_path}/index.html spec/docs/#{version}/apispec.json`\n  end\n\n  task :open, [:version, :docs_path, :host] =\u003e :html do |_, args|\n    version = args[:version] || :v1\n    docs_path = args[:docs_path] || \"api/#{version}/docs\"\n\n    `open public/#{docs_path}/index.html`\n  end\nend\n```\n\n#### Renderers\nYou can render the HTML yourself with ReDoc:\n\n- [Redoc](https://github.com/Redocly/redoc)\n\n### Common issues\n\nYou might experience some strange issues when generating the documentation. Here are a few examples of what we've encountered so far.\n\n#### Uninitialized constant errors\n\nThere 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.\n\nTo fix this issue, generate your documentation with `--require rails_helper`:\n## Development\n\nAfter 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.\n\nTo 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](https://rubygems.org).\n\n## Contributing\n\nBug 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](http://contributor-covenant.org) code of conduct.\n\n\n## Credits\nDox is maintained and sponsored by [Infinum](https://infinum.co).\n\n\u003ca href=\"https://infinum.co\"\u003e\u003cimg alt=\"Infinum\" src=\"infinum.png\" width=\"250\"\u003e\u003c/a\u003e\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinum%2Fdox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfinum%2Fdox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinum%2Fdox/lists"}