From d00bb06e199f88583d17d1b2bcf1c5f12c38ea08 Mon Sep 17 00:00:00 2001 From: PJ Davis Date: Wed, 30 Jan 2019 13:46:13 -0500 Subject: [PATCH] allow headers to be set in the configuration of rswag-api --- README.md | 17 ++++++++-- rswag-api/lib/rswag/api/configuration.rb | 2 +- rswag-api/lib/rswag/api/middleware.rb | 7 ++-- rswag-api/spec/rswag/api/middleware_spec.rb | 36 +++++++++++++++++++++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 08f0157..be84c11 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,9 @@ Once you have an API that can describe itself in Swagger, you've opened the trea ```ruby rails g rswag:install ``` - + Or run the install generators for each package separately if you installed Rswag as separate gems, as indicated above: - + ```ruby rails g rswag:api:install rswag:ui:install RAILS_ENV=test rails g rswag:specs:install @@ -466,6 +466,19 @@ end Note how the filter is passed the rack env for the current request. This provides a lot of flexibilty. For example, you can assign the "host" property (as shown) or you could inspect session information or an Authoriation header and remove operations based on user permissions. +### Custom Headers for Swagger Files ### + +You can specify custom headers for serving your generated Swagger JSON. For example you may want to force a specific charset for the 'Content-Type' header. You can configure a hash of headers to be sent with the request: + +```ruby +Rswag::Api.configure do |c| + ... + + c.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' } +end +``` + + ### Enable Swagger Endpoints for swagger-ui ### You can update the _rswag-ui.rb_ initializer, installed with rswag-ui, to specify which Swagger endpoints should be available to power the documentation UI. If you're using rswag-api, these should correspond to the Swagger endpoints it exposes. When the UI is rendered, you'll see these listed in a drop-down to the top right of the page: diff --git a/rswag-api/lib/rswag/api/configuration.rb b/rswag-api/lib/rswag/api/configuration.rb index ff56180..bf64229 100644 --- a/rswag-api/lib/rswag/api/configuration.rb +++ b/rswag-api/lib/rswag/api/configuration.rb @@ -1,7 +1,7 @@ module Rswag module Api class Configuration - attr_accessor :swagger_root, :swagger_filter + attr_accessor :swagger_root, :swagger_filter, :swagger_headers def resolve_swagger_root(env) path_params = env['action_dispatch.request.path_parameters'] || {} diff --git a/rswag-api/lib/rswag/api/middleware.rb b/rswag-api/lib/rswag/api/middleware.rb index 118c987..658988d 100644 --- a/rswag-api/lib/rswag/api/middleware.rb +++ b/rswag-api/lib/rswag/api/middleware.rb @@ -2,7 +2,7 @@ require 'json' module Rswag module Api - class Middleware + class Middleware def initialize(app, config) @app = app @@ -16,14 +16,15 @@ module Rswag if env['REQUEST_METHOD'] == 'GET' && File.file?(filename) swagger = load_json(filename) @config.swagger_filter.call(swagger, env) unless @config.swagger_filter.nil? + headers = { 'Content-Type' => 'application/json' }.merge(@config.swagger_headers || {}) return [ '200', - { 'Content-Type' => 'application/json' }, + headers, [ JSON.dump(swagger) ] ] end - + return @app.call(env) end diff --git a/rswag-api/spec/rswag/api/middleware_spec.rb b/rswag-api/spec/rswag/api/middleware_spec.rb index aaa148b..6a24e2c 100644 --- a/rswag-api/spec/rswag/api/middleware_spec.rb +++ b/rswag-api/spec/rswag/api/middleware_spec.rb @@ -37,6 +37,42 @@ module Rswag end end + context 'when swagger_headers is configured' do + let(:env) { env_defaults.merge('PATH_INFO' => 'v1/swagger.json') } + + context 'replacing the default content type header' do + before do + config.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' } + end + it 'returns a 200 status' do + expect(response.length).to eql(3) + expect(response.first).to eql('200') + end + + it 'applies the headers to the response' do + expect(response[1]).to include( 'Content-Type' => 'application/json; charset=UTF-8') + end + end + + context 'adding an additional header' do + before do + config.swagger_headers = { 'Access-Control-Allow-Origin' => '*' } + end + it 'returns a 200 status' do + expect(response.length).to eql(3) + expect(response.first).to eql('200') + end + + it 'applies the headers to the response' do + expect(response[1]).to include( 'Access-Control-Allow-Origin' => '*') + end + + it 'keeps the default header' do + expect(response[1]).to include( 'Content-Type' => 'application/json') + end + end + end + context "given a path that doesn't map to any swagger file" do let(:env) { env_defaults.merge('PATH_INFO' => 'foobar.json') } before do