Skip to content

3dcl/jsonapi-swagger

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JSONAPI Swagger

Generate JSONAPI Swagger Doc.

Gem Version GitHub license

jsonapi-swagger-4-2-9.gif

Installation

Add this line to your application's Gemfile:

gem 'jsonapi-swagger'

And then execute:

$ bundle

Or install it yourself as:

$ gem install jsonapi-swagger

Usage

  1. config jsonapi swagger
# config/initializers/swagger.rb
Jsonapi::Swagger.config do |config|
  config.use_rswag = false
  config.version = '3.0.0'
  config.info = { title: 'API V1', version: 'V1'}
  config.file_path = 'v1/swagger.json'
end
  1. generate swagger.json
# gen swagger/v1/swagger.json
bundle exec rails generate jsonapi:swagger User # UserResource < JSONAPI::Resource
  1. additional

use rswag, have to run

# gen swagger/v1/swagger.json
 bundle exec rails rswag:specs:swaggerize
  1. Adjust swagger_helper.rb

It must include the generated schema files into the openapi / swagger file to referenced

require "rails_helper"

RSpec.configure do |config|
  # Specify a root folder where Swagger JSON files are generated
  # NOTE: If you're using the rswag-api to serve API descriptions, you'll need
  # to ensure that it's configured to serve Swagger from the same folder
  config.openapi_root = Rails.root.to_s + "/swagger"



  common_types = Rails.root.join("config", "schemas", "openapi", "types", "common_json_api.schema.json")
  schema_components = JSON.parse(File.read(common_types)).dig("components", "schemas") || {}
  Dir.glob(Rails.root.join("config", "schemas", "openapi", "types", "**.schema.json")).each do |file|

    resource_name = file.split("/").last.split(".").first
    # do not double include the jsonapi types
    next if(resource_name == "common_json_api")

    schema = JSON.parse(File.read(file))
    schema_components[resource_name] = schema
  end

  # Define one or more Swagger documents and provide global metadata for each one
  # When you run the 'rswag:specs:to_swagger' rake task, the complete Swagger will
  # be generated at the provided relative path under swagger_root
  # By default, the operations defined in spec files are added to the first
  # document below. You can override this behavior by adding a swagger_doc tag to the
  # the root example_group in your specs, e.g. describe '...', swagger_doc: 'v2/swagger.json'
  config.openapi_specs = {
    "v1/swagger.json" => {
      openapi: "3.0.0",
      info: {
        title: "API V1",
        version: "v1"
      },
      components: {
        schemas: schema_components
      },
      paths: {
      },

    servers: [
      {
        "url": "{protocol}://{host}/api",
        "variables": {
          "protocol": {
            "enum": ["https"],
            "default": "https"
          },
          "host": {
            "default": "www.example.com"
          }
        }
      }
    ]}
  }
end

Customization

Overriding Types in Resource Classes

If your resource adds attributes that do not map directly to a database column there are in general no type information attached. As a solution to generate matching json schemas and running specs a const can be defined on your resource class providing a hash with more type info.

Example for JSONAPI REsources

class ExampleResource < JSONAPI::Resource

  attributes :subscribed,
    :values,
    :array_min_max

  self.resource_attribute_type_info
    {
      subscribed: { type: :boolean},
      values: {type: :array, 
        # use items type to set the type of the array items
        items_type: :float, 
        comment: 'Explanatory comment, overrides stored database column comment'
      },

      # property of array items can be specified using items_properties
      array_min_max: {
        type: :array,
        # when items_type is :object then items_properties are evaluated
        items_type: :object,
        items_properties: {
          min: {
            type: :number
          },
          max: {
            type: :number
          }
        }
      }

    }
  end

  def subscribed
    current_user = context[:current_user]
    return nil if current_user.nil?

    @model.subscribed_by?(current_user)
  end

  def values
    # an array of numbers
    @model.values
  end
end

Before, After and POST / PATCH data

As it cannot be forseen what is necessary to create a certain resource, there are several methods to adjust the generated code to provide an individual setup for models and to accommodate your authentication / authorization framework

The generated code for before action before { ... }, after action after { ... } and data definition let(:data){ ... } are created using corresponding templates:

  • swagger_base.rb.erb - optional base data and defintions to put on top of each generated spec
  • swagger_before.rb.erb
  • swagger_after.rb.erb
  • swagger_data.rb.erb

It is possible to override them by creating corresponding custom files in lib/generators/jsonapi/swagger/templates

In case you need custom code per resource, create a custom file for resource that preceedes the general templates

  • swagger_before_{resources_name}.rb.erb
  • swagger_after_{resources_name}.rb.erb
  • swagger_data_{resources_name}.rb.erb

RoadMap

  • immutable resources
  • filter/sort resources
  • mutable resources
  • generate swagger.json without rswag

Resource

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/superiorlu/jsonapi-swagger.

About

Create a JSONAPI Swagger.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • HTML 64.3%
  • Ruby 35.5%
  • Shell 0.2%