{"id":13631691,"url":"https://github.com/fotinakis/swagger-blocks","last_synced_at":"2025-04-17T22:31:34.408Z","repository":{"id":20402154,"uuid":"23678202","full_name":"fotinakis/swagger-blocks","owner":"fotinakis","description":"Define and serve live-updating Swagger JSON for Ruby apps.","archived":false,"fork":false,"pushed_at":"2023-01-25T12:32:55.000Z","size":181,"stargazers_count":621,"open_issues_count":36,"forks_count":98,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-09-08T08:54:57.083Z","etag":null,"topics":[],"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/fotinakis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-04T20:28:07.000Z","updated_at":"2024-08-08T15:17:47.000Z","dependencies_parsed_at":"2023-02-14T07:20:14.914Z","dependency_job_id":null,"html_url":"https://github.com/fotinakis/swagger-blocks","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fotinakis%2Fswagger-blocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fotinakis%2Fswagger-blocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fotinakis%2Fswagger-blocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fotinakis%2Fswagger-blocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fotinakis","download_url":"https://codeload.github.com/fotinakis/swagger-blocks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223768631,"owners_count":17199356,"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","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":[],"created_at":"2024-08-01T22:02:34.594Z","updated_at":"2024-11-08T23:31:24.120Z","avatar_url":"https://github.com/fotinakis.png","language":"Ruby","readme":"# Swagger::Blocks\n\n[![Build Status](https://travis-ci.org/fotinakis/swagger-blocks.svg?branch=master)](https://travis-ci.org/fotinakis/swagger-blocks)\n[![Gem Version](https://badge.fury.io/rb/swagger-blocks.svg)](http://badge.fury.io/rb/swagger-blocks)\n\nSwagger::Blocks is a DSL for pure Ruby code blocks that can be turned into JSON.\n\nIt helps you write API docs in the [Swagger](https://helloreverb.com/developers/swagger) style in Ruby and then automatically build JSON that is compatible with [Swagger UI](http://petstore.swagger.wordnik.com/#!/pet).\n\n## Features\n\n* Supports **live updating** by design. Change code, refresh your API docs.\n* **Works with all Ruby web frameworks** including Rails, Sinatra, etc.\n* **100% support** for all features of the [Swagger 2.0](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) spec.\n* Flexible—you can use Swagger::Blocks anywhere, split up blocks to fit your style preferences, etc. Since it's pure Ruby and serves definitions dynamically, you can easily use initializers/config objects to change values or even **show different APIs based on environment**.\n* 1:1 naming with the Swagger spec—block names and nesting should match almost exactly with the swagger spec, with rare exceptions to make things more convenient.\n\n## Swagger UI demo\n\nhttp://petstore.swagger.io/\n\n![swagger-sample](https://cloud.githubusercontent.com/assets/75300/5822830/4769805c-a08c-11e4-9efe-d57cf0f752e0.png)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'swagger-blocks'\n\nOr install directly with `gem install swagger-blocks`.\n\n## Swagger 2.0 example (Rails)\n\nThis is a simplified example based on the objects in the Petstore [Swagger Sample App](http://petstore.swagger.wordnik.com/#!/pet). For a more complex and complete example, see the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) file.\n\nAlso note that **Rails is not required**, you can use Swagger::Blocks in plain Ruby objects.\n\n### PetsController\n\n```Ruby\nclass PetsController \u003c ActionController::Base\n  include Swagger::Blocks\n\n  swagger_path '/pets/{id}' do\n    operation :get do\n      key :summary, 'Find Pet by ID'\n      key :description, 'Returns a single pet if the user has access'\n      key :operationId, 'findPetById'\n      key :tags, [\n        'pet'\n      ]\n      parameter do\n        key :name, :id\n        key :in, :path\n        key :description, 'ID of pet to fetch'\n        key :required, true\n        key :type, :integer\n        key :format, :int64\n      end\n      response 200 do\n        key :description, 'pet response'\n        schema do\n          key :'$ref', :Pet\n        end\n      end\n      response :default do\n        key :description, 'unexpected error'\n        schema do\n          key :'$ref', :ErrorModel\n        end\n      end\n    end\n  end\n  swagger_path '/pets' do\n    operation :get do\n      key :summary, 'All Pets'\n      key :description, 'Returns all pets from the system that the user has access to'\n      key :operationId, 'findPets'\n      key :produces, [\n        'application/json',\n        'text/html',\n      ]\n      key :tags, [\n        'pet'\n      ]\n      parameter do\n        key :name, :tags\n        key :in, :query\n        key :description, 'tags to filter by'\n        key :required, false\n        key :type, :array\n        items do\n          key :type, :string\n        end\n        key :collectionFormat, :csv\n      end\n      parameter do\n        key :name, :limit\n        key :in, :query\n        key :description, 'maximum number of results to return'\n        key :required, false\n        key :type, :integer\n        key :format, :int32\n      end\n      response 200 do\n        key :description, 'pet response'\n        schema do\n          key :type, :array\n          items do\n            key :'$ref', :Pet\n          end\n        end\n      end\n      response :default do\n        key :description, 'unexpected error'\n        schema do\n          key :'$ref', :ErrorModel\n        end\n      end\n    end\n    operation :post do\n      key :description, 'Creates a new pet in the store.  Duplicates are allowed'\n      key :operationId, 'addPet'\n      key :produces, [\n        'application/json'\n      ]\n      key :tags, [\n        'pet'\n      ]\n      parameter do\n        key :name, :pet\n        key :in, :body\n        key :description, 'Pet to add to the store'\n        key :required, true\n        schema do\n          key :'$ref', :PetInput\n        end\n      end\n      response 200 do\n        key :description, 'pet response'\n        schema do\n          key :'$ref', :Pet\n        end\n      end\n      response :default do\n        key :description, 'unexpected error'\n        schema do\n          key :'$ref', :ErrorModel\n        end\n      end\n    end\n  end\n\n  # ...\nend\n```\n\n### Models\n\n#### Pet model\n\n```Ruby\nclass Pet \u003c ActiveRecord::Base\n  include Swagger::Blocks\n\n  swagger_schema :Pet do\n    key :required, [:id, :name]\n    property :id do\n      key :type, :integer\n      key :format, :int64\n    end\n    property :name do\n      key :type, :string\n    end\n    property :tag do\n      key :type, :string\n    end\n  end\n\n  swagger_schema :PetInput do\n    allOf do\n      schema do\n        key :'$ref', :Pet\n      end\n      schema do\n        key :required, [:name]\n        property :id do\n          key :type, :integer\n          key :format, :int64\n        end\n      end\n    end\n  end\n\n  # ...\nend\n```\n\n#### Error model\n\n``` Ruby\nclass ErrorModel  # Notice, this is just a plain ruby object.\n  include Swagger::Blocks\n\n  swagger_schema :ErrorModel do\n    key :required, [:code, :message]\n    property :code do\n      key :type, :integer\n      key :format, :int32\n    end\n    property :message do\n      key :type, :string\n    end\n  end\nend\n```\n\n### Docs controller\n\nTo integrate these definitions with Swagger UI, we need a docs controller that can serve the JSON definitions.\n\n```Ruby\nresources :apidocs, only: [:index]\n```\n\n```Ruby\nclass ApidocsController \u003c ActionController::Base\n  include Swagger::Blocks\n\n  swagger_root do\n    key :swagger, '2.0'\n    info do\n      key :version, '1.0.0'\n      key :title, 'Swagger Petstore'\n      key :description, 'A sample API that uses a petstore as an example to ' \\\n                        'demonstrate features in the swagger-2.0 specification'\n      key :termsOfService, 'http://helloreverb.com/terms/'\n      contact do\n        key :name, 'Wordnik API Team'\n      end\n      license do\n        key :name, 'MIT'\n      end\n    end\n    tag do\n      key :name, 'pet'\n      key :description, 'Pets operations'\n      externalDocs do\n        key :description, 'Find more info here'\n        key :url, 'https://swagger.io'\n      end\n    end\n    key :host, 'petstore.swagger.wordnik.com'\n    key :basePath, '/api'\n    key :consumes, ['application/json']\n    key :produces, ['application/json']\n  end\n\n  # A list of all classes that have swagger_* declarations.\n  SWAGGERED_CLASSES = [\n    PetsController,\n    Pet,\n    ErrorModel,\n    self,\n  ].freeze\n\n  def index\n    render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES)\n  end\nend\n```\n\nThe special part of this controller is this line:\n\n```Ruby\nrender json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES)\n```\n\nThat is the only line necessary to build the full [root Swagger object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schema) JSON and all definitions underneath it. You simply pass in a list of all the \"swaggered\" classes in your app.\n\nIf you want to include controllers outside the standard path just use the full class path including module names, like:\n\n```Ruby\nSWAGGERED_CLASSES = [\n  Api::V1::PetsController,\n  self,\n]\n```\n\nIf you are receiving a \"swagger_root must be declared\" error make sure you are including \"self\" in your SWAGGERED_CLASSES definition, as shown above.\n\nNow, simply point Swagger UI at `/apidocs` and everything should Just Work™. If you change any of the Swagger block definitions, you can simply refresh Swagger UI to see the changes.\n\n### Security handling\n\nTo support Swagger's definitions for API key auth or OAuth2, use `security_definition` in your `swagger_root`:\n\n```Ruby\n  swagger_root do\n    key :swagger, '2.0'\n\n    # ...\n\n    security_definition :api_key do\n      key :type, :apiKey\n      key :name, :api_key\n      key :in, :header\n    end\n    security_definition :petstore_auth do\n      key :type, :oauth2\n      key :authorizationUrl, 'http://swagger.io/api/oauth/dialog'\n      key :flow, :implicit\n      scopes do\n        key 'write:pets', 'modify pets in your account'\n        key 'read:pets', 'read your pets'\n      end\n    end\n  end\n```\n\nYou can then apply [security requirement objects](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#securityRequirementObject) to the entire `swagger_root`, or to individual operations:\n\n```Ruby\n  swagger_path '/pets/{id}' do\n    operation :get do\n\n      # ...\n\n      security do\n        key :api_key, []\n      end\n      security do\n        key :petstore_auth, ['write:pets', 'read:pets']\n      end\n    end\n  end\n```\n\n#### Nested complex objects\n\nThe `key` block simply takes the value you give and puts it directly into the final JSON object. So, if you need to set more complex objects, you can just do:\n\n```ruby\n  key :foo, {some_complex: {nested_object: true}}\n```\n\n#### Parameter referencing\n\nIt is possible to reference parameters rather than explicitly define them in every action in which they are used.\n\nTo define a reusable parameter, declare it within `swagger_root`\nTo reference the parameter, call it within a `swagger_path` or `operation` node\n\n```ruby\nswagger_root do\n  key :swagger, '2.0'\n  # ...\n  parameter :species do\n    key :name, :species\n    key :description, 'Species of this pet'\n  end\nend\n\nswagger_path '/pets/' do\n  operation :post do\n    parameter :species\n    # ...\n  end\nend\n```\n\n#### Inline keys\n\nIt is possible to omit numerous `key` calls using inline hash keys on any block.\n\nAll three calls are equivalent:\n\n```ruby\nparameter do\n  key :paramType, :path\n  key :name, :petId\n  key :description, 'ID of pet that needs to be fetched'\n  key :type, :string\nend\n```\n\n```ruby\nparameter paramType: :path, name: :petId do\n  key :description, 'ID of pet that needs to be fetched'\n  key :type, :string\nend\n```\n\n```ruby\nparameter paramType: :path,\n          name: :petId,\n          description: 'ID of pet that needs to be fetched',\n          type: :string\n```\n\nThese inline keys can be used on any block, not just `parameter` blocks.\n\n#### Writing JSON to a file\n\nIf you are not serving the JSON directly and need to write it to a file for some reason, you can easily use `build_root_json` for that as well:\n\n```Ruby\nswagger_data = Swagger::Blocks.build_root_json(SWAGGERED_CLASSES)\nFile.open('swagger.json', 'w') { |file| file.write(swagger_data.to_json) }\n```\n\n#### Overriding attributes\n\nIf certain attributes must be customized on-the-fly, you can merge a hash containing the customized values on the returned JSON. You can wrap ```build_root_json``` inside your own method:\n\n```Ruby\ndef build_and_override_root_json(overrides = {})\n  Swagger::Blocks.build_root_json(SWAGGERED_CLASSES).merge(overrides)\nend\n```\n\n#### Reducing boilerplate\n\nTo create reusable parameters, please see [parameter referencing](#parameter-referencing).\n\nMost APIs have some common responses for 401s, 404s, etc. Rather than declaring these responses over and over, you can create a reusable module.\n\n```ruby\nmodule SwaggerResponses\n  module AuthenticationError\n    def self.extended(base)\n      base.response 401 do\n        key :description, 'not authorized'\n        schema do\n          key :'$ref', :AuthenticationError\n        end\n      end\n    end\n  end\nend\n```\n\nNow, you just need to extend it:\n\n```ruby\noperation :post do\n  extend SwaggerResponses::AuthenticationError\n  # ...\n  response 200 do\n    # ...\n  end\nend\n```\n\n## Reference\n\nSee the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) for examples of more complex features and declarations possible.\n\n### Swagger 1.2\n\nThe old [Swagger 1.2](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md) spec is not supported in swagger-blocks \u003e= 2.0.0, but you may use [1.4.0](https://github.com/fotinakis/swagger-blocks/tree/v1.4.0).\n\n## Contributing\n\n1. Fork it ( https://github.com/fotinakis/swagger-blocks/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\nThrow a ★ on it! :)\n\n## Filing issues\n\n**Please DO [file an issue](https://github.com/fotinakis/swagger-blocks/issues)**:\n\n- If you find a bug or some part of the Swagger 2.0 spec that swagger-blocks does not support.\n- To propose and discuss a code change before submitting a PR for it.\n- To talk about anything related specifically to swagger-blocks, not Swagger itself.\n\n**Please DO NOT file an issue**:\n\n- If you have a question about Swagger or Swagger UI. We simply cannot support all Swagger-related questions. Check out the http://swagger.io/community/ for help.\n\n## Release notes\n\n* v2.0.1: Bugfix to allow nested arrays of `items`.\n* v2.0.0: Code cleanup, drop support for Swagger 1.2 spec.\n* v1.4.0: Allow parameters to be defined once in swagger_root and reused.\n* v1.3.4: Fix support for fully-qualified URIs in `$ref` values.\n* v1.3.3: Bugfix to allow `parameter` inside `swagger_path`.\n* v1.3.2: Bugfix to allow `property` inside `items` for rare extended schema uses.\n* v1.3.1: Bugfix to allow nested objects via `property` nested in `property`.\n* v1.3.0: Added support for condensed syntax via inline keys on every block.\n* v1.2.0: Improved support for `$ref` Path Item Object parameters.\n* v1.1.3: Rename tags directive to tag for consistency.\n* v1.1.2: Bugfix for security definition support.\n* v1.1.1: Bugfix for tags node support.\n* v1.1: Support for Swagger 2.0 spec.\n* v1.0.1: Make backwards-compatible with Ruby 1.9.3.\n* v1.0.0: Initial major release.\n\n## Credits\n\nThanks to [@ali-graham](https://github.com/ali-graham) for contributing support for Swagger 2.0.\n\nOriginal idea inspired by [@richhollis](https://github.com/richhollis/)'s [swagger-docs](https://github.com/richhollis/swagger-docs/) gem.\n","funding_links":[],"categories":["Ruby","Documentation"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffotinakis%2Fswagger-blocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffotinakis%2Fswagger-blocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffotinakis%2Fswagger-blocks/lists"}