{"id":48970743,"url":"https://github.com/s13g/docit","last_synced_at":"2026-04-18T07:01:54.952Z","repository":{"id":349900004,"uuid":"1204445143","full_name":"S13G/docit","owner":"S13G","description":"Simple, flexible, automatic API documentation for Ruby APIs.","archived":false,"fork":false,"pushed_at":"2026-04-16T19:07:18.000Z","size":689,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-16T21:12:11.113Z","etag":null,"topics":["openapi-generator","openapi-specification","openapi3","restapi","ruby","ruby-on-rails","swagger"],"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/S13G.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-08T02:38:10.000Z","updated_at":"2026-04-16T19:07:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/S13G/docit","commit_stats":null,"previous_names":["s13g/docket"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/S13G/docit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/S13G%2Fdocit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/S13G%2Fdocit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/S13G%2Fdocit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/S13G%2Fdocit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/S13G","download_url":"https://codeload.github.com/S13G/docit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/S13G%2Fdocit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31959884,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"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":["openapi-generator","openapi-specification","openapi3","restapi","ruby","ruby-on-rails","swagger"],"created_at":"2026-04-18T07:01:54.037Z","updated_at":"2026-04-18T07:01:54.947Z","avatar_url":"https://github.com/S13G.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docit\n\n[![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.2-red.svg)](https://www.ruby-lang.org)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nDecorator-style API documentation for Ruby on Rails. Write OpenAPI 3.0.3 docs with clean controller DSL macros, separate doc modules, or AI-assisted scaffolding for undocumented endpoints.\n\n### Scalar (default)\n![Scalar API Reference](docs/images/scalar_image.png)\n\n### Swagger\n![Swagger UI](docs/images/swagger_image.png)\n\n## Table Of Contents\n\n- Getting started\n  - [Installation](#installation)\n  - [Configuration](#configuration)\n  - [Usage](#usage)\n- Documentation styles\n  - [Style 1: Inline (simple APIs)](#style-1-inline-simple-apis)\n  - [Style 2: Separate doc files (recommended for larger APIs)](#style-2-separate-doc-files-recommended-for-larger-apis)\n- Endpoint DSL reference\n  - [Endpoint documentation DSL](#endpoint-documentation-dsl)\n  - [Request bodies](#request-bodies)\n  - [Path parameters](#path-parameters)\n  - [Enums](#enums)\n  - [Security](#security)\n  - [Deprecated endpoints](#deprecated-endpoints)\n  - [Nested objects and arrays](#nested-objects-and-arrays)\n  - [Response examples](#response-examples)\n  - [Shared schemas (`$ref`)](#shared-schemas-ref)\n  - [File uploads](#file-uploads)\n- AI documentation\n  - [AI Automatic Documentation](#ai-automatic-documentation)\n  - [Quick start (included in install)](#quick-start-included-in-install)\n  - [Standalone commands](#standalone-commands)\n  - [Supported providers](#supported-providers)\n  - [What the AI generates](#what-the-ai-generates)\n- Runtime and development\n  - [Documentation UIs](#documentation-uis)\n  - [How it works](#how-it-works)\n  - [Mounting at a different path](#mounting-at-a-different-path)\n  - [JSON spec only](#json-spec-only)\n  - [Development](#development)\n  - [Contributing](#contributing)\n  - [License](#license)\n- Project docs\n  - [CHANGELOG](CHANGELOG.md)\n  - [CONTRIBUTING](CONTRIBUTING.md)\n  - [CODE OF CONDUCT](CODE_OF_CONDUCT.md)\n\n## Installation\n\nAdd Docit to your Gemfile:\n\n```ruby\ngem \"docit\"\n```\n\nThen run:\n\n```bash\nbundle install\nrails generate docit:install\n```\n\nThe install generator does everything in one step:\n\n1. Creates `config/initializers/docit.rb` with default settings\n2. Mounts the documentation engine at `/api-docs` in your routes\n3. Asks how you'd like to set up your docs:\n   - **AI automatic docs** — configure an AI provider, then Docit scans your routes and generates complete documentation for every endpoint\n   - **Manual docs** — Docit scans your routes and creates scaffolded doc files with TODO placeholders, injects `use_docs` into controllers, and lets you fill in the details\n   - **Skip** — just install the base config and set up docs later\n\nVisit `/api-docs` to see your interactive API documentation (Scalar by default, Swagger UI also available at `/api-docs/swagger`).\n\nIf you choose AI setup, Docit stores your provider config in `.docit_ai.yml` with restricted file permissions and adds that file to `.gitignore` when possible.\n\n## Configuration\n\nEdit `config/initializers/docit.rb`:\n\n```ruby\nDocit.configure do |config|\n  config.title       = \"My API\"\n  config.version     = \"1.0.0\"\n  config.description = \"Backend API documentation\"\n\n  # Documentation UI: :scalar (default) or :swagger\n  config.default_ui  = :scalar\n\n  # Authentication: pick one (or multiple):\n  config.auth :bearer                              # Bearer token (JWT by default)\n  config.auth :basic                               # HTTP Basic\n  config.auth :api_key, name: \"X-API-Key\",         # API key in header\n                         location: \"header\"\n\n  # Tag descriptions (shown in the documentation sidebar):\n  config.tag \"Users\", description: \"User account management\"\n  config.tag \"Auth\",  description: \"Authentication endpoints\"\n\n  # Server URLs (shown in the server dropdown):\n  config.server \"https://api.example.com\", description: \"Production\"\n  config.server \"https://staging.example.com\", description: \"Staging\"\n  config.server \"http://localhost:3000\", description: \"Development\"\nend\n```\n\n## Usage\n\nDocit supports two styles for documenting endpoints. Choose whichever fits your project or mix both.\n\n### Style 1: Inline (simple APIs)\n\nAdd `swagger_doc` blocks directly in your controller:\n\n```ruby\nclass Api::V1::UsersController \u003c ApplicationController\n  swagger_doc :index do\n    summary \"List all users\"\n    tags \"Users\"\n    response 200, \"Users retrieved\"\n  end\n  def index\n    # your code\n  end\nend\n```\n\n### Style 2: Separate doc files (recommended for larger APIs)\n\nKeep controllers clean by defining docs in dedicated files:\n\n```ruby\n# app/docs/api/v1/users_docs.rb\nmodule Api::V1::UsersDocs\n  extend Docit::DocFile\n\n  doc :index do\n    summary \"List all users\"\n    description \"Returns a paginated list of users\"\n    tags \"Users\"\n\n    parameter :page, location: :query, type: :integer, description: \"Page number\"\n\n    response 200, \"Users retrieved\" do\n      property :users, type: :array, items: :object do\n        property :id, type: :integer, example: 1\n        property :email, type: :string, example: \"user@example.com\"\n      end\n      property :total, type: :integer, example: 42\n    end\n  end\n\n  doc :create do\n    summary \"Create a user\"\n    tags \"Users\"\n\n    request_body required: true do\n      property :email, type: :string, required: true\n      property :password, type: :string, required: true, format: :password\n    end\n\n    response 201, \"User created\" do\n      property :id, type: :integer\n    end\n\n    response 422, \"Validation failed\" do\n      property :errors, type: :object do\n        property :email, type: :array, items: :string\n      end\n    end\n  end\nend\n\n# app/controllers/api/v1/users_controller.rb — stays clean!\nclass Api::V1::UsersController \u003c ApplicationController\n  use_docs Api::V1::UsersDocs\n\n  def index\n    # pure business logic\n  end\n\n  def create\n    # pure business logic\n  end\nend\n```\n\nYou can also mix both styles — use `use_docs` for most actions and add inline `swagger_doc` for one-offs:\n\n```ruby\nclass Api::V1::UsersController \u003c ApplicationController\n  use_docs Api::V1::UsersDocs        # loads :index and :create from doc file\n\n  swagger_doc :destroy do             # inline doc for this one action\n    summary \"Delete user\"\n    tags \"Users\"\n    response 204, \"Deleted\"\n  end\n\n  def index; end\n  def create; end\n  def destroy; end\nend\n```\n\n### Endpoint documentation DSL\n\nThe following examples work in both `swagger_doc` blocks and `doc` blocks.\n\n### Request bodies\n\n```ruby\nswagger_doc :create do\n  summary \"Create a user\"\n  tags \"Users\"\n\n  request_body required: true do\n    property :email, type: :string, required: true, example: \"user@example.com\"\n    property :password, type: :string, required: true, format: :password\n    property :name, type: :string, example: \"Jane Doe\"\n    property :profile, type: :object do\n      property :bio, type: :string\n      property :avatar_url, type: :string, format: :uri\n    end\n  end\n\n  response 201, \"User created\" do\n    property :id, type: :integer, example: 1\n    property :email, type: :string, example: \"user@example.com\"\n  end\n\n  response 422, \"Validation failed\" do\n    property :errors, type: :object do\n      property :email, type: :array, items: :string\n    end\n  end\nend\ndef create\n  # your code\nend\n```\n\n### Path parameters\n\n```ruby\nswagger_doc :show do\n  summary \"Get a user\"\n  tags \"Users\"\n\n  parameter :id, location: :path, type: :integer, required: true, description: \"User ID\"\n\n  response 200, \"User found\" do\n    property :id, type: :integer, example: 1\n    property :email, type: :string\n    property :name, type: :string\n  end\n\n  response 404, \"User not found\" do\n    property :error, type: :string, example: \"Not found\"\n  end\nend\ndef show\n  # your code\nend\n```\n\n### Enums\n\n```ruby\nswagger_doc :index do\n  summary \"List orders\"\n  tags \"Orders\"\n\n  parameter :status, location: :query, type: :string,\n            enum: %w[pending shipped delivered],\n            description: \"Filter by status\"\n\n  response 200, \"Orders list\" do\n    property :orders, type: :array do\n      property :id, type: :integer\n      property :status, type: :string, enum: %w[pending shipped delivered]\n    end\n  end\nend\n```\n\n### Security\n\nMark endpoints as requiring authentication:\n\n```ruby\nswagger_doc :destroy do\n  summary \"Delete a user\"\n  tags \"Users\"\n  security :bearer_auth      # references the scheme from your config\n\n  response 204, \"User deleted\"\n  response 401, \"Unauthorized\"\nend\n```\n\n### Deprecated endpoints\n\n```ruby\nswagger_doc :legacy_search do\n  summary \"Search (legacy)\"\n  tags \"Search\"\n  deprecated\n\n  response 200, \"Results\"\nend\n```\n\n### Nested objects and arrays\n\n```ruby\nresponse 200, \"Success\" do\n  property :user, type: :object do\n    property :id, type: :integer\n    property :name, type: :string\n    property :addresses, type: :array do\n      property :street, type: :string\n      property :city, type: :string\n      property :zip, type: :string\n    end\n  end\nend\n```\n\n### Response examples\n\n```ruby\nresponse 200, \"User found\" do\n  property :id, type: :integer\n  property :email, type: :string\n\n  example \"admin_user\",\n          { id: 1, email: \"admin@example.com\" },\n          description: \"An admin user\"\n\n  example \"regular_user\",\n          { id: 2, email: \"user@example.com\" },\n          description: \"A regular user\"\nend\n```\n\n### Shared schemas (`$ref`)\n\nDefine reusable schemas once and reference them across multiple endpoints:\n\n```ruby\n# In config/initializers/docit.rb or a dedicated file:\nDocit.define_schema :User do\n  property :id,    type: :integer, example: 1\n  property :email, type: :string,  example: \"user@example.com\"\n  property :name,  type: :string,  example: \"Jane Doe\"\n  property :address, type: :object do\n    property :street, type: :string\n    property :city,   type: :string\n  end\nend\n\nDocit.define_schema :Error do\n  property :error,   type: :string, example: \"Not found\"\n  property :details, type: :array, items: :string\nend\n```\n\nReference them in any endpoint with `schema ref:`:\n\n```ruby\nswagger_doc :show do\n  summary \"Get user\"\n  tags \"Users\"\n\n  response 200, \"User found\" do\n    schema ref: :User\n  end\n\n  response 404, \"Not found\" do\n    schema ref: :Error\n  end\nend\n\nswagger_doc :create do\n  summary \"Create user\"\n  tags \"Users\"\n\n  request_body required: true do\n    schema ref: :User\n  end\n\n  response 201, \"Created\" do\n    schema ref: :User\n  end\nend\n```\n\nThis outputs `$ref: '#/components/schemas/User'` in the spec — Swagger UI resolves it automatically.\n\n### File uploads\n\nUse `type: :file` with `content_type: \"multipart/form-data\"` for file upload endpoints:\n\n```ruby\nswagger_doc :upload_avatar do\n  summary \"Upload avatar\"\n  tags \"Users\"\n\n  request_body required: true, content_type: \"multipart/form-data\" do\n    property :avatar, type: :file, required: true, description: \"Avatar image\"\n    property :caption, type: :string\n  end\n\n  response 201, \"Avatar uploaded\" do\n    property :url, type: :string, format: :uri\n  end\nend\n```\n\n`type: :file` maps to `{ type: \"string\", format: \"binary\" }` in the OpenAPI spec.\n\n## AI Automatic Documentation\n\nDocit can generate complete API documentation using AI. This works with OpenAI, Anthropic, or Groq (free tier available).\n\n### Quick start (included in install)\n\nWhen you run `rails generate docit:install` and choose option 1 (AI automatic docs), everything is set up automatically — provider configuration, doc generation, controller wiring, and tag injection.\n\nBefore the first AI request, Docit warns that your controller source code will be sent to the selected provider and asks for confirmation in interactive terminals.\n\n### Standalone commands\n\nYou can also set up AI docs separately:\n\n```bash\n# Configure your AI provider (one-time setup)\nrails generate docit:ai_setup\n\n# Generate docs for all undocumented endpoints\nrails docit:autodoc\n\n# Generate docs for a specific controller\nrails docit:autodoc[Api::V1::UsersController]\n\n# Preview what would be generated without writing files\nDRY_RUN=1 rails docit:autodoc\n```\n\n### Supported providers\n\n| Provider   | Notes |\n|------------|-------|\n| OpenAI     | Requires API key from platform.openai.com |\n| Anthropic  | Requires API key from console.anthropic.com |\n| Groq       | Free tier at console.groq.com |\n\nAll providers automatically retry on rate-limit (429) errors with exponential backoff, so free-tier usage works out of the box.\n\nAI configuration is stored in `.docit_ai.yml`.\nIf your app does not have a `.gitignore`, add `.docit_ai.yml` manually.\n\n### What the AI generates\n\nFor each undocumented endpoint, Docit:\n\n1. Reads the controller source code\n2. Inspects the route (HTTP method, path, parameters)\n3. Writes the generated doc block to `app/docs/`\n4. Injects `use_docs` into the controller\n5. Adds tag descriptions to the initializer\n\nDo not use AI autodoc on controllers that contain secrets, proprietary business rules, or internal comments you do not want sent to an external provider.\n\n## Documentation UIs\n\nDocit ships with two documentation UIs, both reading from the same OpenAPI spec:\n\n| Path | UI | Notes |\n|------|------|-------|\n| `/api-docs` | Default (Scalar) | Configurable via `config.default_ui` |\n| `/api-docs/scalar` | Scalar API Reference | Modern UI with built-in API client, dark mode, code samples |\n| `/api-docs/swagger` | Swagger UI | Classic OpenAPI explorer |\n| `/api-docs/spec` | Raw JSON | OpenAPI 3.0.3 spec |\n\nBoth UIs include a navigation bar to switch between them. Set `config.default_ui = :swagger` to make Swagger the default at `/api-docs`.\n\n## How it works\n\n1. `swagger_doc` registers an **Operation** for each controller action in a global **Registry**\n2. When someone visits `/api-docs/spec`, Docit's **SchemaGenerator** combines all registered operations with your Rails routes (via **RouteInspector**) to produce an OpenAPI 3.0.3 JSON document\n3. The **Engine** serves the configured documentation UI at `/api-docs`, pointing it at the generated spec\n\nThe DSL is included in all controllers automatically via a Rails Engine initializer — no manual `include` needed if you're using `ActionController::API` or `ActionController::Base`.\n\n## Mounting at a different path\n\nIn `config/routes.rb`:\n\n```ruby\nmount Docit::Engine =\u003e \"/docs\"        # now at /docs instead of /api-docs\n```\n\n## JSON spec only\n\nIf you just want the raw OpenAPI JSON (e.g., for code generation):\n\n```\nGET /api-docs/spec\n```\n\n## Development\n\n```bash\ngit clone https://github.com/S13G/docit.git\ncd docit\nbundle install\nbundle exec rspec        # run all tests\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on [GitHub](https://github.com/S13G/docit).\n\n## License\n\n[MIT](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs13g%2Fdocit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs13g%2Fdocit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs13g%2Fdocit/lists"}