# OasCore Documentation > This is the book with the documentation for configure and usage OasCore engine. # Introduction OasCore is a Ruby gem designed to generate Open API Specification (OAS) 3.1 documentation directly from YARD comments in your endpoints. It serves as the core engine for OAS generation, while framework-specific adapters like `OasRails` (for Ruby on Rails) handle the extraction, integration and additional features. ### Key Features - 🚀 **OAS 3.1 Generation**: OasCore generates OAS version 3.1, the latest standard, ensuring your API documentation is up-to-date. - 📝 **YARD-Powered Documentation**: Simply annotate your endpoints with YARD tags to include descriptions, parameters, and examples—no need to learn a new DSL or rely on framework-specific tools. - 🔌 **Framework Agnostic**: OasCore is designed to work with any Ruby framework. Adapters like `OasRails` extend its functionality for specific frameworks. ### Demo App (OasRails) 🔗 **[Open Demo App](https://paso.fly.dev/api/docs)** 👤 **Username**: `oasrails` 🔑 **Password**: `oasrails` # OasRails ![Screenshot of OasCore](../assets/rails_theme.png) ## Installation 1. Add this line to your Rails application's Gemfile: ```ruby gem "oas_rails"` ``` 2. Execute: ```bash bundle ``` 3. Mount the engine in your config/routes.rb file ```ruby mount OasRails::Engine => '/docs' ``` You'll now have **basic documentation** based on your routes and automatically gathered information at `localhost:3000/docs`. To enhance it, create an initializer file and add [Yard](https://yardoc.org/) tags to your controller methods. # Configuring OasRails To configure OasRails, **you MUST create an initializer file** including all your settings. The first step is to create your initializer file, which you can easily do with: ```bash rails generate oas_rails:config ``` Then fill it with your data. Below are the available configuration options: ### Basic Information about the API - `config.info.title`: The title of your API documentation. - `config.info.summary`: A brief summary of your API. - `config.info.description`: A detailed description of your API. This can include markdown formatting and will be displayed prominently in your documentation. - `config.info.contact.name`: The name of the contact person or organization. - `config.info.contact.email`: The contact email address. - `config.info.contact.url`: The URL for more information or support. ### Servers Information - `config.servers`: An array of server objects, each containing `url` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#server-object). ### Tag Information - `config.tags`: An array of tag objects, each containing `name` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#tag-object). ### Optional Settings - `config.include_mode`: Determines the mode for including operations. The default value is `all`, which means it will include all route operations under the `api_path`, whether documented or not. Other possible values: - `:with_tags`: Includes in your OAS only the operations with at least one tag. Example: Not included: ```ruby def update end ``` Included: ```ruby # @summary Return all Books def index end ``` - `:explicit`: Includes in your OAS only the operations tagged with `@oas_include`. Example: Not included: ```ruby def update end ``` Included: ```ruby # @oas_include def index end ``` - `config.api_path`: Sets the API path if your API is under a different namespace than the root. This is important to configure if you have the `include_mode` set to `all` because it will include all routes of your app in the final OAS. For example, if your app has additional routes and your API is under the namespace `/api`, set this configuration as follows: ```ruby config.api_path = "/api" ``` - `config.rapidoc_configuration`: expects to be set as a string key => value hash. It is merged with defaults which can be found in [the OAsRailsHelper](https://github.com/a-chacon/oas_rails/blob/main/app/helpers/oas_rails/oas_rails_helper.rb). Any duplicate keys will override these. Refer to Rapidocs for any others. Defaults to `{}` ```ruby config.rapidoc_configuration = {"show-header" => "true"} ``` - `config.rapidoc_logo_url`: expects a string, it is used as a source for an img tag so any valid img tag source should work. Defaults to `nil` ```ruby config.rapidoc_logo_url = "/assets/some_random_image.png" ``` - `config.ignored_actions`: Defines an array of controller or controller#action pairs. You do not need to prepend the `api_path`. This is useful when you want to include all routes except a few specific actions or when an external engine (e.g., Devise) adds routes to your API. - `config.default_tags_from`: Determines the source of default tags for operations. Can be set to `:namespace` or `:controller`. The first option means that if your endpoint is in the route `/users/:id`, it will be tagged with `Users`. If set to `controller`, the tag will be `UsersController`. - `config.http_verbs`: Defaults to `[:get, :post, :put, :patch, :delete]` ### Authentication Settings - `config.authenticate_all_routes_by_default`: Determines whether to authenticate all routes by default. Default is `true`. - `config.security_schema`: The default security schema used for authentication. Choose from the following predefined options: - `:api_key_cookie`: API key passed via HTTP cookie. - `:api_key_header`: API key passed via HTTP header. - `:api_key_query`: API key passed via URL query parameter. - `:basic`: HTTP Basic Authentication. - `:bearer`: Bearer token (generic). - `:bearer_jwt`: Bearer token formatted as a JWT (JSON Web Token). - `:mutual_tls`: Mutual TLS authentication (mTLS). - `config.security_schemas`: Custom security schemas. Follow the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#security-scheme-object) for defining these schemas. ### Default Errors - **`config.set_default_responses`**: Determines whether to add default error responses to endpoints. Default is `true`. - **`config.possible_default_responses`**: An array of possible default error responses. Some responses are added conditionally based on the endpoint (e.g., `:not_found` only applies to `show`, `update`, or `delete` actions). **Default**: `[:not_found, :unauthorized, :forbidden, :internal_server_error, :unprocessable_entity]` **Allowed Values**: Symbols representing HTTP status codes from the list: `[:not_found, :unauthorized, :forbidden, :internal_server_error, :unprocessable_entity]` - **`config.response_body_of_default`**: The response body template for default error responses. Must be a string representing a hash, similar to those used in request body tags. **Default**: `"Hash{ message: String }"` - **`config.response_body_of_{code symbol}`**: Customizes the response body for specific error responses. Must be a string representing a hash, similar to `response_body_of_default`. If not specified, it defaults to the value of `response_body_of_default`. **Examples**: ```ruby # Customize the response body for "unprocessable_entity" errors config.response_body_of_unprocessable_entity = "Hash{ errors: Array }" # Customize the response body for "forbidden" errors config.response_body_of_forbidden = "Hash{ code: Integer, message: String }" ``` ### Project License - `config.info.license.name`: The title name of your project's license. Default: GPL 3.0 - `config.info.license.url`: The URL to the full license text. Default: # Enabling CORS for Interactive Documentation By default, OasRails uses **RapiDoc** as the frontend for interactive API documentation. However, you can customize this to use other tools like Swagger UI or ReDoc if needed. To test endpoints interactively using RapiDoc (or your chosen frontend), you must enable Cross-Origin Resource Sharing (CORS) in your Rails application. Follow these steps: 1. **Add the `rack-cors` gem** to your `Gemfile` (Or uncomment): ```ruby gem 'rack-cors' ``` 2. **Run `bundle install`** to install the gem. 3. **Configure CORS** in `config/initializers/cors.rb` (create the file if it doesn't exist): ```ruby Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '*' # For development, allow all origins. Restrict this in production. resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: false # Set to `true` if using cookies or authentication headers. end end ``` 4. **Restart your Rails server** for the changes to take effect. This will allow RapiDoc to make requests to your API endpoints from the browser. # Securing the OasRails Engine To secure the OasRails engine, which exposes an endpoint for showing the OAS definition, you can configure authentication to ensure that only authorized users have access. Here are a few methods to achieve this: ### 1. Using Basic Authentication Use basic authentication to protect the OasRails endpoint. You can set this up in an initializer: ```ruby # config/initializers/oas_core.rb OasRails::Engine.middleware.use(Rack::Auth::Basic) do |username, password| ActiveSupport::SecurityUtils.secure_compare(Rails.application.credentials.oas_core_username, username) & ActiveSupport::SecurityUtils.secure_compare(Rails.application.credentials.oas_core_password, password) end ``` ### 2. Using Devise's `authenticate` Helper You can use Devise's `authenticate` helper to restrict access to the OasRails endpoint. For example, you can allow only admin users to access the endpoint: ```ruby # config/routes.rb # ... authenticate :user, ->(user) { user.admin? } do mount OasRails::Engine, at: '/docs' end ``` ### 3. Custom Authentication To support custom authentication, you can extend the OasRails' ApplicationController using a hook. This allows you to add custom before actions to check for specific user permissions: ```ruby # config/initializers/oas_core.rb ActiveSupport.on_load(:oas_core_application_controller) do # context here is OasRails::ApplicationController before_action do raise ActionController::RoutingError.new('Not Found') unless current_user&.admin? end def current_user # Load the current user User.find(session[:user_id]) # Adjust according to your authentication logic end end ``` # Customizing the View The OasRails engine provides an easy way to display your OpenAPI Specification (OAS) within your Rails application. By default, it includes an `index` view in the `OasCoreController` that displays [RapiDoc](https://rapidocweb.com/) through a CDN with default configurations. You can easily override this view to replace RapiDoc entirely or configure it differently. ### Available configurations #### Changing the UI Theme You can customize the appearance of the OAS documentation UI by setting the `config.rapidoc_theme` option in the initializer file. The default theme is `"rails"`, but you can choose from the following predefined themes: - **dark**: Dark background with light text. - **light**: Light background with dark text. - **night**: Dark theme with a blueish tint. - **mud**: Dark theme with brownish tones. - **coffee**: Dark theme with warm brown tones. - **forest**: Dark theme with greenish tones. - **olive**: Dark theme with olive tones. - **outerspace**: Dark theme with a space-like feel. - **ebony**: Dark theme with deep blue tones. - **snow**: Light theme with a clean white background. - **green**: Light theme with green accents. - **blue**: Light theme with blue accents. - **beige**: Light theme with a beige background. - **graynav**: Light theme with a gray navigation bar. - **purplenav**: Light theme with a purple navigation bar. - **lightgraynav**: Light theme with a light gray navigation bar. - **darkbluenav**: Light theme with a dark blue navigation bar. - **rails**: Default theme with Rails-inspired colors (red accents). #### How to Configure the Theme To change the theme, add the following line to your `config/initializers/oas_rails.rb` file: ```ruby OasRails.configure do |config| config.rapidoc_theme = "dark" # Replace "dark" with your preferred theme name end ``` Any other modification will require that you overwrite the index view explained in the next steps. ### Overriding the `index` View To override the `index` view provided by the OasRails engine, follow these steps: 1. **Create the Override View File**: In your host application, create a new file at the path `app/views/oas_rails/oas_rails/index.html.erb`. If the directories do not exist, you will need to create them. 2. **Customize the View**: Open the newly created `index.html.erb` file and add your custom HTML and ERB code to display the OAS as desired. You can refer to the source code of this project for guidance. ### Overriding/Adding rapid-doc inline styles To override styles in rapidoc we can use [parts](https://rapidocweb.com/css-parts.html). If you do not override the default index then there is a partial available for override `app/views/oas_rails/oas_rails/_rapidoc_style_parts.html.erb`. Please see its [default for a starting point](https://github.com/a-chacon/oas_rails/blob/main/app/views/oas_rails/oas_rails/_rapidoc_style_parts.html.erb). #### Using the Custom View Once the custom view file is in place, Rails will automatically use it instead of the view provided by the OasRails engine. This allows you to fully customize the presentation of the OAS without modifying the engine's code. # Configuring the Source OAS For more complex scenarios, it is highly recommended to use a **source OAS (OpenAPI Specification)** file. This file serves as a centralized repository for reusable objects (such as schemas, request bodies, parameters, and responses) that can be referenced across your API documentation. This approach promotes consistency and reduces redundancy. ## Basic Configuration To set up a source OAS file, configure the path in your `OasRails` configuration block: ```ruby OasRails.configure do |config| config.source_oas_path = "lib/assets/oas.json" # Path to your source OAS file end ``` ## Example Source OAS File Below is an example of an `oas.json` file containing reusable components, such as a `User` schema: ```json { "components": { "schemas": { "User": { "type": "object", "properties": { "name": { "type": "string", "description": "The user's full name" }, "email": { "type": "string", "format": "email", "description": "The user's email address" }, "age": { "type": "integer", "description": "The user's age", "minimum": 0 }, "password": { "type": "string", "description": "The user's password", "minLength": 6 } }, "required": [ "name", "email", "password" ], "example": { "name": "John Doe", "email": "john.doe@example.com", "age": 30, "password": "securepassword123" } } }, "requestBodies": { ... }, "parameters": { ... }, ... } } ``` ## Referencing Reusable Components Once your source OAS file is configured, you can reference its components in your API documentation tags. For example, to reference the `User` schema in a response: ```markdown # @response Created User (200) [Reference:#/components/schemas/User] ``` ### Key Benefits 1. **Consistency**: Ensures uniformity across your API documentation. 2. **Reusability**: Eliminates duplication by centralizing common objects. 3. **Maintainability**: Simplifies updates, as changes to the source OAS propagate automatically to all references. ### Supported References You can reference the **schemas** of **request bodies, responses, and parameters** using the main tag. For example: ```markdown # @request_body Required User [Reference:#/components/schemas/User] ``` Alternatively, you can **reference the entire request body, response, or parameter** using the reference tags: ```markdown # @request_body_ref #/components/requestBodies/createUser ``` # OasHanami **Please note that this implementation is not yet thoroughly tested and is in an early stage. If you encounter any issues or have suggestions, feel free to open a GitHub issue, PR, or discussion [here](https://github.com/a-chacon/oas_hanami).** ![Screenshot of OasHanami](../assets/hanami_theme.png) # Installation 1. Add this line to your Hanami application's Gemfile: ```ruby gem "oas_namai"` ``` 2. Execute: ```bash bundle ``` 3. Mount the engine in your config/routes.rb file **at the bottom of all routes** to ensure it doesn't interfere with your application's routing: ```ruby mount OasHanami::Web::View, at: "/docs" ``` 4. **The most important step:** add the route inspector before starting the app. It can be do in your `config.ru` file: ```ruby require "hanami/boot" Hanami.app.router(inspector: OasHanami::Inspector.new) # set before run the app. run Hanami.app ``` You'll now have **basic documentation** based on your routes and automatically gathered information at `localhost:2300/docs`. To enhance it, create an initializer file and add [Yard](https://yardoc.org/) tags to your controller methods. # Configuring OasHanami To configure OasHanami, according to the [official documentation](https://guides.hanamirb.org/v2.1/app/providers/), you need to create a provider file that includes all your settings. The first step is to create your initializer file as follows: ```ruby # config/providers/oas_hanami.rb Hanami.app.register_provider(:oas_hanami) do prepare do require "oas_hanami" end start do OasHanami.configure do |config| config.info.title = "Amazing Hanami API" end end end ``` Then fill it with your data. Below are the available configuration options: ### Basic Information about the API - `config.info.title`: The title of your API documentation. - `config.info.summary`: A brief summary of your API. - `config.info.description`: A detailed description of your API. This can include markdown formatting and will be displayed prominently in your documentation. - `config.info.contact.name`: The name of the contact person or organization. - `config.info.contact.email`: The contact email address. - `config.info.contact.url`: The URL for more information or support. ### Servers Information - `config.servers`: An array of server objects, each containing `url` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#server-object). ### Tag Information - `config.tags`: An array of tag objects, each containing `name` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#tag-object). ### Optional Settings - `config.include_mode`: Determines the mode for including operations. The default value is `all`, which means it will include all route operations under the `api_path`, whether documented or not. Other possible values: - `:with_tags`: Includes in your OAS only the operations with at least one tag. Example: Not included: ```ruby def update end ``` Included: ```ruby # @summary Return all Books def index end ``` - `:explicit`: Includes in your OAS only the operations tagged with `@oas_include`. Example: Not included: ```ruby def update end ``` Included: ```ruby # @oas_include def index end ``` - `config.api_path`: Sets the API path if your API is under a different namespace than the root. This is important to configure if you have the `include_mode` set to `all` because it will include all routes of your app in the final OAS. For example, if your app has additional routes and your API is under the namespace `/api`, set this configuration as follows: ```ruby config.api_path = "/api" ``` - `config.http_verbs`: Defaults to `[:get, :post, :put, :patch, :delete]` ### Authentication Settings - `config.authenticate_all_routes_by_default`: Determines whether to authenticate all routes by default. Default is `true`. - `config.security_schema`: The default security schema used for authentication. Choose from the following predefined options: - `:api_key_cookie`: API key passed via HTTP cookie. - `:api_key_header`: API key passed via HTTP header. - `:api_key_query`: API key passed via URL query parameter. - `:basic`: HTTP Basic Authentication. - `:bearer`: Bearer token (generic). - `:bearer_jwt`: Bearer token formatted as a JWT (JSON Web Token). - `:mutual_tls`: Mutual TLS authentication (mTLS). - `config.security_schemas`: Custom security schemas. Follow the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#security-scheme-object) for defining these schemas. ### Project License - `config.info.license.name`: The title name of your project's license. Default: GPL 3.0 - `config.info.license.url`: The URL to the full license text. Default: # Configuring the Source OAS For more complex scenarios, it is highly recommended to use a **source OAS (OpenAPI Specification)** file. This file serves as a centralized repository for reusable objects (such as schemas, request bodies, parameters, and responses) that can be referenced across your API documentation. This approach promotes consistency and reduces redundancy. ## Basic Configuration To set up a source OAS file, configure the path in your `OasHanami` configuration block: ```ruby OasHanami.configure do |config| config.source_oas_path = "lib/oas.json" # Path to your source OAS file end ``` ## Example Source OAS File Below is an example of an `oas.json` file containing reusable components, such as a `User` schema: ```json { "components": { "schemas": { "User": { "type": "object", "properties": { "name": { "type": "string", "description": "The user's full name" }, "email": { "type": "string", "format": "email", "description": "The user's email address" }, "age": { "type": "integer", "description": "The user's age", "minimum": 0 }, "password": { "type": "string", "description": "The user's password", "minLength": 6 } }, "required": [ "name", "email", "password" ], "example": { "name": "John Doe", "email": "john.doe@example.com", "age": 30, "password": "securepassword123" } } }, "requestBodies": { ... }, "parameters": { ... }, ... } } ``` ## Referencing Reusable Components Once your source OAS file is configured, you can reference its components in your API documentation tags. For example, to reference the `User` schema in a response: ```markdown # @response Created User (200) [Reference:#/components/schemas/User] ``` ### Key Benefits 1. **Consistency**: Ensures uniformity across your API documentation. 2. **Reusability**: Eliminates duplication by centralizing common objects. 3. **Maintainability**: Simplifies updates, as changes to the source OAS propagate automatically to all references. ### Supported References You can reference the **schemas** of **request bodies, responses, and parameters** using the main tag. For example: ```markdown # @request_body Required User [Reference:#/components/schemas/User] ``` Alternatively, you can **reference the entire request body, response, or parameter** using the reference tags: ```markdown # @request_body_ref #/components/requestBodies/createUser ``` # OasGrape **Please note that this implementation is not yet thoroughly tested and is in an early stage. If you encounter any issues or have suggestions, feel free to open a GitHub issue, pull request (PR), or discussion [here](https://github.com/a-chacon/oas_grape).** The usage can be a bit tricky. Unlike other frameworks, this cannot be implemented as a simple method comment because Grape does not use methods—only lambdas that are called and loaded once. As a result, live reloading of documentation does not work here. ## Usage As mentioned earlier, the implementation in Grape differs from other frameworks. The tag comments must be placed inside the `detail` key of a `desc` block. Everything inside this key is parsed as a comment, and this is where the OAS YARD tags should be included. Example code: ```ruby desc "Returns a list of Users." do detail <<~OAS_GRAPE # @summary Returns a list of Users. # @parameter offset(query) [Integer] Used for pagination of response data. default: (0) minimum: (0) # @parameter limit(query) [Integer] Maximum number of items per page. default: (25) minimum: (1) maximum: (100) # @parameter status(query) [Array] Filter by status. enum: (active,inactive,deleted) # @parameter X-front(header) [String] Header for identifying the front. minLength: (1) maxLength: (50) # @response Success response(200) [Array] # @response_example Success(200) # [ JSON # [ # { "id": 1, "name": "John", "email": "john@example.com" }, # { "id": 2, "name": "Jane", "email": "jane@example.com" } # ] # ] OAS_GRAPE end get do { users: @@users } end ``` # Installation This guide will walk you through the steps to install and integrate the `oas_grape` gem into your Grape API project. ## Prerequisites - A Ruby on Rails or Grape API project. - Basic familiarity with Grape and OpenAPI Specification (OAS). ## Steps ### 1. Add the Gem to Your Project Include the `oas_grape` gem in your `Gemfile`: ```ruby gem 'oas_grape' ``` Run `bundle install` to install the gem. ### 2. Integrate with Your Grape API In your main API file (e.g., `api.rb`), require the gem and mount the OAS documentation viewer: ```ruby require "oas_grape" module Dummy class API < Grape::API format :json # Mount your API endpoints mount Dummy::UsersAPI mount Dummy::NotesAPI # ... add other endpoints as needed # Mount the OAS documentation viewer mount OasGrape::Web::View, at: "/docs" end end ``` ### 3. Access the Documentation After starting your server, navigate to `/docs` in your browser to view the interactive API documentation. # Configuration To customize `oas_grape` for your API documentation needs, follow these steps: 1. **Create a Configuration File**: We recommend creating a dedicated file (e.g., `oas_grape_configuration.rb`) to centralize all your settings. This ensures maintainability and clarity. 2. **Load the Configuration**: Require this file in your main application file (e.g., `api.rb` or `application.rb`) to apply the configurations globally. 3. **Available Settings**: Below is a comprehensive list of configurations you can customize for your API documentation: ### Basic Information about the API - `config.info.title`: The title of your API documentation. - `config.info.summary`: A brief summary of your API. - `config.info.description`: A detailed description of your API. This can include markdown formatting and will be displayed prominently in your documentation. - `config.info.contact.name`: The name of the contact person or organization. - `config.info.contact.email`: The contact email address. - `config.info.contact.url`: The URL for more information or support. ### Servers Information - `config.servers`: An array of server objects, each containing `url` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#server-object). ### Tag Information - `config.tags`: An array of tag objects, each containing `name` and `description` keys. For more details, refer to the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#tag-object). ### Optional Settings - `config.include_mode`: Determines the mode for including operations. The default value is `all`, which means it will include all route operations under the `api_path`, whether documented or not. Other possible values: - `:with_tags`: Includes in your OAS only the operations with at least one tag. Example: Not included: ```ruby def update end ``` Included: ```ruby # @summary Return all Books def index end ``` - `:explicit`: Includes in your OAS only the operations tagged with `@oas_include`. Example: Not included: ```ruby def update end ``` Included: ```ruby # @oas_include def index end ``` - `config.api_path`: Sets the API path if your API is under a different namespace than the root. This is important to configure if you have the `include_mode` set to `all` because it will include all routes of your app in the final OAS. For example, if your app has additional routes and your API is under the namespace `/api`, set this configuration as follows: ```ruby config.api_path = "/api" ``` - `config.http_verbs`: Defaults to `[:get, :post, :put, :patch, :delete]` ### Authentication Settings - `config.authenticate_all_routes_by_default`: Determines whether to authenticate all routes by default. Default is `true`. - `config.security_schema`: The default security schema used for authentication. Choose from the following predefined options: - `:api_key_cookie`: API key passed via HTTP cookie. - `:api_key_header`: API key passed via HTTP header. - `:api_key_query`: API key passed via URL query parameter. - `:basic`: HTTP Basic Authentication. - `:bearer`: Bearer token (generic). - `:bearer_jwt`: Bearer token formatted as a JWT (JSON Web Token). - `:mutual_tls`: Mutual TLS authentication (mTLS). - `config.security_schemas`: Custom security schemas. Follow the [OpenAPI Specification](https://spec.openapis.org/oas/latest.html#security-scheme-object) for defining these schemas. ### Project License - `config.info.license.name`: The title name of your project's license. Default: GPL 3.0 - `config.info.license.url`: The URL to the full license text. Default: # Tags In addition to the information provided in the initializer file and the data that can be extracted from the routes and methods automatically, it is essential to document your API in the following way. The documentation is created **with the help of YARD**, so the methods are documented with **comment tags**. ## Documenting Your Endpoints Almost every tag description in an OAS file supports **markdown formatting** (e.g., bold, italics, lists, links) for better readability in the generated documentation. Additionally, **multi-line descriptions** are supported. When using multi-line descriptions, ensure the content is indented at least one space more than the tag itself to maintain proper formatting. For example: ```ruby # @request_body_example Simple User [Hash] # { # user: { # name: "Oas", # email: "oas@test.com", # password: "Test12345" # } # } ``` You can use these tags in your controller methods to enhance the automatically generated documentation. Remember to use markdown formatting in your descriptions for better readability in the generated OAS document. ## Summary Below is a summary of all available tags for documenting your API endpoints: ### Authentication Tags - **`@auth`**: Specifies security mechanisms for the endpoint (e.g., `# @auth [bearer, basic]`). - **`@no_auth`**: Removes security requirements for the endpoint (e.g., `# @no_auth`). ### Inclusion Tags - **`@oas_include`**: Explicitly includes the endpoint in the OAS file when `include_mode` is `:explicit` (e.g., `# @oas_include`). ### Parameter Tags - **`@parameter`**: Documents a parameter for the endpoint (e.g., `# @parameter page(query) [Integer] The page number.`). - **`@parameter_ref`**: References a predefined parameter (e.g., `# @parameter_ref #/components/parameters/user_id`). ### Request Body Tags - **`@request_body`**: Describes the request body (e.g., `# @request_body The user to be created [!User]`). - **`@request_body_example`**: Provides examples for the request body (e.g., `# @request_body_example basic user [Hash] {user: {name: "Oas"}}`). - **`@request_body_ref`**: References a predefined request body (e.g., `# @request_body_ref #/components/requestBodies/user`). ### Response Tags - **`@response`**: Documents the endpoint's responses (e.g., `# @response User not found by the provided Id(404) [Hash]`). - **`@response_example`**: Provides examples for responses (e.g., `# @response_example Invalid Email(422) [{success: "false"}]`). - **`@response_ref`**: References a predefined response (e.g., `# @response_ref (200) #/components/responses/success`). ### Metadata Tags - **`@summary`**: Adds a custom summary for the endpoint (e.g., `# @summary This endpoint creates a User`). - **`@tags`**: Tags the endpoint for categorization (e.g., `# @tags Users, Admin`). For detailed usage and examples, refer to the individual tag documentation files. # @summary **Structure**: `@summary text` Used to add a summary to the endpoint. It replaces the default summary/title of the endpoint. **Example**: `# @summary This endpoint creates a User` ``` # @summary This endpoint # creates a User ``` # @parameter **Structure**: `@parameter name(position) [type] text [keyword: (value)]` Represents a parameter for the endpoint. The position can be one of the following: `header`, `path`, `cookie`, or `query`. The type should be a valid Ruby class, such as `String`, `Integer`, or `Array`. Prefix the class with a `!` to indicate a required parameter. ### Supported Keywords in Descriptions You can include additional schema keywords in the description using the format `keyword: (value)`. The following keywords are supported: - **`default`**: The default value for the parameter. Example: `default: (1)` - **`minimum`**: The minimum value for numeric parameters. Example: `minimum: (0)` - **`maximum`**: The maximum value for numeric parameters. Example: `maximum: (100)` - **`enum`**: A comma-separated list of allowed values. Example: `enum: (red,green,blue)` - **`format`**: The format of the parameter (e.g., `date`, `uuid`). Example: `format: (uuid)` - **`pattern`**: A regex pattern for string validation. Example: `pattern: (^[A-Za-z]+$)` - **`nullable`**: Whether the parameter can be `null` (`true` or `false`). Example: `nullable: (true)` - **`exclusiveMinimum`**: Whether the `minimum` is exclusive (`true` or `false`). Example: `exclusiveMinimum: (true)` - **`exclusiveMaximum`**: Whether the `maximum` is exclusive (`true` or `false`). Example: `exclusiveMaximum: (false)` - **`minLength`**: The minimum length for string parameters. Example: `minLength: (3)` - **`maxLength`**: The maximum length for string parameters. Example: `maxLength: (50)` **Examples**: ```ruby # Basic usage # @parameter page(query) [!Integer] The page number. default: (1) minimum: (0) # Enum and nullable # @parameter color(query) [String] The color of the item. enum: (red,green,blue) nullable: (true) # String validation # @parameter username(path) [String] The username. pattern: (^[A-Za-z0-9_]+$), minLength: (3), maxLength: (20) ``` ## From Swagger docs: Common Mistakes There are two common mistakes when using the default keyword: - Using default with required parameters or properties, for example, with path parameters. This does not make sense – if a value is required, the client must always send it, and the default value is never used. - Using default to specify a sample value. This is not intended use of default and can lead to unexpected behavior in some Swagger tools. Use the example or examples keyword for this purpose instead. See Adding Examples. # @parameter_ref **Structure**: `@parameter_ref text` Document a parameter using a custom reference. This tag allows you to reference predefined parameters or external resources, making your API documentation more modular and reusable. ### Usage - **`text`**: A reference to the parameter definition. This can be: - An internal reference (e.g., `#/components/parameters/user_id`). - An external URL (e.g., `https://example.com/parameters/user_id.json`). ### Examples 1. **Internal Reference**: ```markdown # @parameter_ref #/components/parameters/user_id ``` This references a predefined user ID parameter in your OpenAPI components. 2. **External Resource**: ```markdown # @parameter_ref https://example.com/parameters/user_id.json ``` This references an external resource for a user ID parameter, useful for shared documentation across services. # @request_body **Structure**: `@request_body text [type]` Documents the request body needed by the endpoint. The structure is optional if you provide a valid Active Record class. Use `!` to indicate a required request body. **One line example**: `# @request_body The user to be created [!User]` `# @request_body The user to be created [User]` **Multi-line example**: ```ruby # @request_body User to be created # [ # !Hash{ # user: Hash{ # name: String, # email: String, # age: Integer, # cars: Array< # Hash{ # identifier: String # } # > # } # } # ] ``` #### Content type By default, the content type defined for a request body is "application/json". You can change it by passing a custom content type between parentheses after the text. Example: ```ruby # @request_body User (multipart/form-data) [Hash{ user: String }] ``` ### Reference This tag also supports a reference for its schema. The reference can be to anything you want, external or internal resources, following the definition of OAS . The reference should be passed like this: ``` # @request_body The user to be created [Reference:#/components/schema/userRequest] ``` Notice that the reference here **is for the schema and not for the entire request body**. If you need to reference the complete request body, consider using `@request_body_ref`. # @request_body_ref **Structure**: `@request_body_ref text` Document a request body using a custom reference. This tag allows you to reference predefined request bodies or external resources, making your API documentation more modular and reusable. ### Usage - **`text`**: A reference to the request body definition. This can be: - An internal reference (e.g., `#/components/requestBodies/user`). - An external URL (e.g., `https://example.com/request_bodies/user.json`). ### Examples 1. **Internal Reference**: ```markdown # @request_body_ref #/components/requestBodies/user ``` This references a predefined user request body in your OpenAPI components. 2. **External Resource**: ```markdown # @request_body_ref https://example.com/request_bodies/user.json ``` This references an external resource for a user request body, useful for shared documentation across services. # @request_body_example **Structure**: `@request_body_example text [type]` Adds examples to the provided request body. **One line example**: `# @request_body_example A complete User. [JSON{"user": {"name": 'Luis', "age": 30, "password": 'MyWeakPassword123'}}]` **Multi-line example**: ```ruby # @request_body_example basic user # [JSON{ # "user": { # "name": "Oas", # "email": "oas@test.com", # "password": "Test12345" # } # } # ] ``` **It should be valid JSON; don't forget that keys must be enclosed in quotes ("").** # @response **Structure**: `@response text(code) [type]` Documents the responses of the endpoint and overrides the default responses found by the engine. **One line example**: `# @response User not found by the provided Id(404) [Hash{success: Boolean, message: String}]` `# @response Validation errors(422) [Hash{success: Boolean, errors: Array}>}]` **Multi-line example**: ```ruby # @response A test response from an Issue(405) # [ # Hash{ # message: String, # data: Hash{ # availabilities: Array, # dates: Array # } # } # ] ``` ### Reference This tag also supports a reference for its schema. The reference can be to anything you want, external or internal resources, following the definition of OAS . The reference should be passed like this: ``` # @response User not found by the provided Id(404) [Reference:#/components/schema/errorResponse] ``` Notice that the reference here **is for the schema and not for the entire response**. If you need to reference the complete response, consider using `@response_ref`. # @response_ref **Structure**: `@response_ref (code) text` Document a response using a custom reference. This tag allows you to reference predefined responses or external resources, making your API documentation more modular and reusable. ### Usage - **`code`**: The HTTP status code for the response (e.g., `200`, `404`, `500`). - **`text`**: A reference to the response definition. This can be: - An internal reference (e.g., `#/components/responses/success`). - An external URL (e.g., `https://example.com/responses/not_found`). ### Examples 1. **Internal Reference**: ```markdown # @response_ref (200) #/components/responses/success ``` This references a predefined success response in your OpenAPI components. 2. **Error Response**: ```markdown # @response_ref (500) #/components/responses/error ``` This references a predefined error response in your OpenAPI components. 3. **External Resource**: ```markdown # @response_ref (404) https://example.com/responses/not_found.json ``` This references an external resource for a "Not Found" response, useful for shared documentation across services. # @response_example **Structure**: `@response_example text(code) [Type]` Documents response examples of the endpoint associated to a response code. **One line example**: `# @response_example Invalida Email(422) [JSON{"success": "false", "errors": [{"field": "email", "type": "email", "detail": ["Invalid email"]}] }]` `# @response_example Id not exists (404) [{"success": "false", "message": "Nothing found with the provided ID." }]` **Multi-line example**: ```ruby # @response_example Another 405 Error (405) # [JSON{ # { # "message": "another", # "data": { # "availabilities": [ # "three" # ], # "dates": [] # } # } # }] ``` **It should be valid JSON; don't forget that keys must be enclosed in quotes ("").** # @tags **Structure**: `@tags Tag1,Tag2,Tag3` Tags your endpoints. You can define these tags in the initializer file for documentation purposes, but it is not required to predefine them before use. This tag accepts a string where tags are separated by commas (`,`). Each value becomes a tag for the documented endpoint. **Examples**: ```ruby # @tags Users ``` ```ruby # @tags Project, Admin ``` # @no_auth **Structure**: `@no_auth` This tag will remove any security requirement from the endpoint. Useful when most of your endpoints require authentication and only a few do not.(Ex: Login, Registration...) **Example**: `# @no_auth` # @auth **Structure**: `@auth [types]` This tag will set which security mechanisms can be used for the endpoint. The security mechanisms MUST be defined previously in the initializer file. **Example**: `# @auth [bearer, basic]` # @oas_include Use this tag to explicitly include endpoints in the final OpenAPI Specification (OAS) file **when `include_mode` is set to `:explicit`**. Only endpoints annotated with `@oas_include` will be included. ## Usage Add the `@oas_include` tag as a comment above the endpoint you want to document. For example: ### Endpoint Not Included (Default Behavior) ```ruby def update end ``` ### Endpoint Included (With `@oas_include`) ```ruby # @oas_include def index end ``` # Examples ```ruby class UsersController < ApplicationController before_action :set_user, only: %i[show update destroy] # @summary Returns a list of Users. # # @parameter offset(query) [Integer] Used for pagination of response data (default: 25 items per response). Specifies the offset of the next block of data to receive. # @parameter status(query) [Array] Filter by status. (e.g. status[]=inactive&status[]=deleted). # @parameter X-front(header) [String] Header for identify the front. def index @users = User.all end # @summary Get a user by id. # @auth [bearer] # # This method show a User by ID. The id must exist of other way it will be returning a **`404`**. # # @parameter id(path) [Integer] Used for identify the user. # @response Requested User(200) [Hash] {user: {name: String, email: String, created_at: DateTime }} # @response User not found by the provided Id(404) [Hash] {success: Boolean, message: String} # @response You don't have the right permission for access to this resource(403) [Hash] {success: Boolean, message: String} def show render json: @user end # @summary Create a User # @no_auth # # @request_body The user to be created. At least include an `email`. [!User] # @request_body_example basic user [Hash] {user: {name: "Luis", email: "luis@gmail.ocom"}} def create @user = User.new(user_params) if @user.save render json: @user, status: :created else render json: { success: false, errors: @user.errors }, status: :unprocessable_entity end end # A `user` can be updated with this method # - There is no option # - It must work # @tags users, update # @request_body User to be created [!Hash{user: { name: String, email: !String, age: Integer, available_dates: Array}}] # @request_body_example Update user [Hash] {user: {name: "Luis", email: "luis@gmail.com"}} # @request_body_example Complete User [Hash] {user: {name: "Luis", email: "luis@gmail.com", age: 21}} def update if @user.update(user_params) render json: @user else render json: @user.errors, status: :unprocessable_entity end end # @summary Delete a User # Delete a user and his associated data. def destroy @user.destroy! redirect_to users_url, notice: 'User was successfully destroyed.', status: :see_other end private # Use callbacks to share common setup or constraints between actions. def set_user @user = User.find(params[:id]) end # Only allow a list of trusted parameters through. def user_params params.require(:user).permit(:name, :email) end end ``` # LLMs Documentation (llms.txt) OasCore generates `.txt` files optimized for AI integration: - [llms.txt](/oas_core/llms.txt): Provides the basics to understand the structure and functionality of OasCore. (Work in progress) - [llms-full.txt](/oas_core/llms-full.txt): Offers a full description of how to use OasCore and document endpoints. (**Currently recommended**) ## How It Works (in 3 Steps) ### 1. Choose the File OasCore generates `.txt` files optimized for AI tools. ### 2. Load It Into Your Tool You can load these files into any AI tool or editor that supports external context. For this example, I used Cursor. **This is not a tool I recommend** because it is closed-source, but it worked for the example. ### 3. Ask Questions Naturally Examples of questions you can ask: - *"How to document JWT authentication in OasCore?"* - *"Document the endpoint..."* - *"Add examples of possible request bodies for the create method."*