mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-23 06:16:42 +00:00
Support multiple swagger documents. Add custom_ui_generator. Update readme
This commit is contained in:
parent
df4b9c80c9
commit
4b40fb9efe
87
README.md
87
README.md
@ -1,2 +1,85 @@
|
||||
# swagger-rails
|
||||
Seamlessly adds a Swagger to Rails-based API's
|
||||
swagger-rails
|
||||
=========
|
||||
|
||||
Seamlessly adds a [Swagger](http://swagger.io/) to Rails-based API's! You create one or more swagger.json files to describe your API and swagger-rails will serve it up along with an embedded version of the [swagger-ui](https://github.com/swagger-api/swagger-ui). This means you can complement your API with a slick discovery UI to assist consumers with their integration efforts. Best of all, it requires minimal coding and maintenance, allowing you to focus on building an awesome API!
|
||||
|
||||
And that's not all ...
|
||||
|
||||
Once you have a Web API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. See [swagger-codegen](https://github.com/swagger-api/swagger-codegen) for more details.
|
||||
|
||||
## Getting Started ##
|
||||
|
||||
1. Add this line to your applications _Gemfile_:
|
||||
|
||||
```ruby
|
||||
gem swagger_rails
|
||||
```
|
||||
|
||||
2. Run the install generator
|
||||
|
||||
```ruby
|
||||
rails g swagger_rails:install
|
||||
```
|
||||
|
||||
3. Spin up your app and navigate to '/api-docs'
|
||||
|
||||
_This is where your awesome API docs and playground can be viewed_
|
||||
|
||||
4. Update the sample swagger.json (under config/swagger/v1) to describe your API
|
||||
|
||||
_Swagger is a well thought-out and intuitive format so referring to samples will help in getting started. For some of the finer details, you shoud refer to the spec_
|
||||
|
||||
* _The Demo JSON: http://petstore.swagger.io/v2/swagger.json_
|
||||
* _The Demo UI: http://petstore.swagger.io/_
|
||||
* _The Spec.: http://swagger.io/specification/_
|
||||
|
||||
## How does it Work? ##
|
||||
|
||||
The install generator will add the following entry to your applications _routes.rb_
|
||||
|
||||
```ruby
|
||||
mount SwaggerRails::Engine => '/api-docs'
|
||||
```
|
||||
|
||||
This will wire up routes for the swagger-ui assets and the raw JSON descriptions, all prefixed with "/api-docs". For example, if you navigate to "/api-docs/index.html" you'll get the swagger-ui. If you navigate to "/api-docs/v1/swagger.json", you'll get the sample swagger.json that's installed into your app directory at "config/swagger/v1/swagger.json".
|
||||
|
||||
If you'd like your Swagger resources to appear under a different base path, you can change the Engine mount point from "/api-docs" to something else.
|
||||
|
||||
By default, the swagger-ui will request a service description at "<mount-point>/v1/swagger.json" and then use that to generate the slick documentation and playground UI. If you'd like to change the path to your JSON descriptions or create multiple descriptions, you can change the folder structure and files under "config/swagger". For example, you could describe different versions of your API as follows
|
||||
|
||||
```
|
||||
|-- app
|
||||
|-- config
|
||||
|-- swagger
|
||||
|-- v1
|
||||
|-- swagger.json
|
||||
|-- v2
|
||||
|-- swagger.json
|
||||
|-- v3
|
||||
|-- swagger.json
|
||||
```
|
||||
|
||||
This will expose each of those descriptions as JSON endpoints. Next, you'll need to tell swagger-ui which of these endpoints you want to provide documentation for. This can be configured in the initializer that's installed at "config/initializers/swagger_rails":
|
||||
|
||||
```ruby
|
||||
SwaggerRails.configure do |c|
|
||||
|
||||
c.swagger_docs = {
|
||||
'API V1' => 'v1/swagger.json',
|
||||
'API V2' => 'v2/swagger.json',
|
||||
'API V3' => 'v3/swagger.json'
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
Now, if you view the swagger-ui, you'll notice that each of these are available in the select box at the top right of the page, allowing you to navigate between the documentations for each version.
|
||||
|
||||
## Customizing the UI ##
|
||||
|
||||
The swagger-ui provides several options for customizing it's behavior, all of which are documented here https://github.com/swagger-api/swagger-ui#swaggerui. If you need to tweak these or customize the overall look and feel of your swagger-ui, then you'll need to provide your own version of index.html. You can do this with the following generator.
|
||||
|
||||
```ruby
|
||||
rails g swagger_rails:custom_ui
|
||||
```
|
||||
|
||||
This will add a local version that you can customize at "app/views/swagger_rails/swagger_ui/index.html.erb"
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
module SwaggerRails
|
||||
class ApplicationController < ActionController::Base
|
||||
|
||||
def redirect_to_swagger_ui
|
||||
redirect_to swagger_ui_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,6 +2,12 @@ module SwaggerRails
|
||||
class SwaggerUiController < ApplicationController
|
||||
|
||||
def index
|
||||
@discovery_paths = Hash[
|
||||
SwaggerRails.swagger_docs.map do |name, path|
|
||||
[ name, "#{root_path}#{path}" ]
|
||||
end
|
||||
]
|
||||
|
||||
render :index, layout: false
|
||||
end
|
||||
end
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
if (url && url.length > 1) {
|
||||
url = decodeURIComponent(url[1]);
|
||||
} else {
|
||||
url = "<%= SwaggerRails.swagger_docs.values.first %>";
|
||||
url = "<%= @discovery_paths.values.first %>";
|
||||
}
|
||||
|
||||
// Pre load translate...
|
||||
@ -110,7 +110,7 @@
|
||||
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
|
||||
<div class='input'>
|
||||
<select id="select_version">
|
||||
<% SwaggerRails.swagger_docs.each do |name, path| %>
|
||||
<% @discovery_paths.each do |name, path| %>
|
||||
<option value="<%= path %>"><%= name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
SwaggerRails::Engine.routes.draw do
|
||||
root to: 'application#redirect_to_swagger_ui'
|
||||
get '/index.html', to: 'swagger_ui#index', as: :swagger_ui
|
||||
end
|
||||
|
||||
8
lib/generators/swagger_rails/custom_ui/USAGE
Normal file
8
lib/generators/swagger_rails/custom_ui/USAGE
Normal file
@ -0,0 +1,8 @@
|
||||
Description:
|
||||
Adds a local version of index.html.erb for customizing the swagger-ui
|
||||
|
||||
Example:
|
||||
rails generate swagger_rails:custom_ui
|
||||
|
||||
This will create:
|
||||
app/views/swagger_rails/swagger_ui/index.html.erb
|
||||
@ -0,0 +1,9 @@
|
||||
module SwaggerRails
|
||||
class CustomUiGenerator < Rails::Generators::Base
|
||||
source_root File.expand_path('../files', __FILE__)
|
||||
|
||||
def add_custom_index
|
||||
copy_file('index.html.erb', 'app/views/swagger_rails/swagger_ui/index.html.erb')
|
||||
end
|
||||
end
|
||||
end
|
||||
145
lib/generators/swagger_rails/custom_ui/files/index.html.erb
Normal file
145
lib/generators/swagger_rails/custom_ui/files/index.html.erb
Normal file
@ -0,0 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
|
||||
<link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||
<link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
|
||||
<link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
|
||||
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
|
||||
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
|
||||
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
|
||||
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
|
||||
<script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
|
||||
<script src='lib/underscore-min.js' type='text/javascript'></script>
|
||||
<script src='lib/backbone-min.js' type='text/javascript'></script>
|
||||
<script src='swagger-ui.js' type='text/javascript'></script>
|
||||
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
|
||||
<script src='lib/marked.js' type='text/javascript'></script>
|
||||
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
|
||||
|
||||
<!-- Some basic translations -->
|
||||
<!-- <script src='lang/translator.js' type='text/javascript'></script> -->
|
||||
<!-- <script src='lang/ru.js' type='text/javascript'></script> -->
|
||||
<!-- <script src='lang/en.js' type='text/javascript'></script> -->
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var url = window.location.search.match(/url=([^&]+)/);
|
||||
if (url && url.length > 1) {
|
||||
url = decodeURIComponent(url[1]);
|
||||
} else {
|
||||
url = "<%= @discovery_paths.values.first %>";
|
||||
}
|
||||
|
||||
// Pre load translate...
|
||||
if(window.SwaggerTranslator) {
|
||||
window.SwaggerTranslator.translate();
|
||||
}
|
||||
window.swaggerUi = new SwaggerUi({
|
||||
url: url,
|
||||
dom_id: "swagger-ui-container",
|
||||
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
|
||||
onComplete: function(swaggerApi, swaggerUi){
|
||||
if(typeof initOAuth == "function") {
|
||||
initOAuth({
|
||||
clientId: "your-client-id",
|
||||
clientSecret: "your-client-secret",
|
||||
realm: "your-realms",
|
||||
appName: "your-app-name",
|
||||
scopeSeparator: ","
|
||||
});
|
||||
}
|
||||
|
||||
if(window.SwaggerTranslator) {
|
||||
window.SwaggerTranslator.translate();
|
||||
}
|
||||
|
||||
$('pre code').each(function(i, e) {
|
||||
hljs.highlightBlock(e)
|
||||
});
|
||||
|
||||
addApiKeyAuthorization();
|
||||
},
|
||||
onFailure: function(data) {
|
||||
log("Unable to Load SwaggerUI");
|
||||
},
|
||||
docExpansion: "list",
|
||||
apisSorter: "alpha",
|
||||
showRequestHeaders: false
|
||||
});
|
||||
|
||||
function addApiKeyAuthorization(){
|
||||
var key = encodeURIComponent($('#input_apiKey')[0].value);
|
||||
if(key && key.trim() != "") {
|
||||
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
|
||||
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
|
||||
log("added key " + key);
|
||||
}
|
||||
}
|
||||
|
||||
$('#input_apiKey').change(addApiKeyAuthorization);
|
||||
|
||||
// if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
|
||||
/*
|
||||
var apiKey = "myApiKeyXXXX123456789";
|
||||
$('#input_apiKey').val(apiKey);
|
||||
*/
|
||||
|
||||
window.swaggerUi.load();
|
||||
|
||||
function log() {
|
||||
if ('console' in window) {
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="swagger-section">
|
||||
<div id='header'>
|
||||
<div class="swagger-ui-wrap">
|
||||
<a id="logo" href="http://swagger.io">swagger</a>
|
||||
<form id='api_selector'>
|
||||
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text" disabled="disabled"/></div>
|
||||
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
|
||||
<div class='input'>
|
||||
<select id="select_version">
|
||||
<% @discovery_paths.each do |name, path| %>
|
||||
<option value="<%= path %>"><%= name %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<script type="text/javascript">
|
||||
$('#select_version').change(function () {
|
||||
$('#input_baseUrl').val($(this).val());
|
||||
window.swaggerUi.headerView.showCustom();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#select_version {
|
||||
border: none;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-ms-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
background-color: #547f00;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
|
||||
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
|
||||
</body>
|
||||
</html>
|
||||
@ -12,5 +12,9 @@ module SwaggerRails
|
||||
def add_initializer
|
||||
template('swagger_rails.rb', 'config/initializers/swagger_rails.rb')
|
||||
end
|
||||
|
||||
def add_routes
|
||||
route("mount SwaggerRails::Engine => '/api-docs'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"info": {
|
||||
"version": "0.0.0",
|
||||
"title": "[Enter a description for your API here]",
|
||||
"description": "The docs below are powered by the default swagger.json installed with swagger_rails. Please update it to describe your API. See here for the complete swagger spec - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md"
|
||||
"description": "The docs below are powered by the default swagger.json that gets installed with swagger_rails. You'll need to update it to describe your API. See here for the complete swagger spec - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md"
|
||||
},
|
||||
"paths": {
|
||||
"/a/sample/resource": {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
SwaggerRails.configure do |c|
|
||||
|
||||
# List the names and paths of Swagger
|
||||
# List the names and paths (relative to config/swagger) of Swagger
|
||||
# documents you'd like to expose in your swagger-ui
|
||||
c.swagger_docs = {
|
||||
'API V1' => '/swagger/v1/swagger.json'
|
||||
'API V1' => 'v1/swagger.json'
|
||||
}
|
||||
end
|
||||
|
||||
@ -9,9 +9,8 @@ module SwaggerRails
|
||||
class << self
|
||||
attr_accessor :swagger_docs
|
||||
|
||||
#Defaults
|
||||
@@swagger_docs = {
|
||||
'V1' => '/swagger/v1/swagger.json'
|
||||
'V1' => 'v1/swagger.json'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
SwaggerRails.configure do |c|
|
||||
|
||||
# List the names and paths of Swagger
|
||||
# List the names and paths (relative to config/swagger) of Swagger
|
||||
# documents you'd like to expose in your swagger-ui
|
||||
c.swagger_docs = {
|
||||
'API V1' => '/swagger/v1/swagger.json',
|
||||
'API V2' => '/swagger/v2/swagger.json'
|
||||
'API V1' => 'v1/swagger.json'
|
||||
}
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Rails.application.routes.draw do
|
||||
mount SwaggerRails::Engine => '/api-docs'
|
||||
|
||||
mount SwaggerRails::Engine => '/swagger'
|
||||
end
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"info": {
|
||||
"version": "0.0.0",
|
||||
"title": "[Enter a description for your API here]",
|
||||
"description": "The docs below are powered by the default swagger.json that was installed with swagger_rails. You can update it to describe your API. See here for the complete swagger spec - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md"
|
||||
"description": "The docs below are powered by the default swagger.json that gets installed with swagger_rails. You'll need to update it to describe your API. See here for the complete swagger spec - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md"
|
||||
},
|
||||
"paths": {
|
||||
"/a/sample/resource": {
|
||||
|
||||
2
spec/generators/fixtures/config/routes.rb
Normal file
2
spec/generators/fixtures/config/routes.rb
Normal file
@ -0,0 +1,2 @@
|
||||
Rails.application.routes.draw do
|
||||
end
|
||||
16
spec/generators/swagger_rails/custom_ui_generator_spec.rb
Normal file
16
spec/generators/swagger_rails/custom_ui_generator_spec.rb
Normal file
@ -0,0 +1,16 @@
|
||||
require 'rails_helper'
|
||||
require 'generators/swagger_rails/custom_ui/custom_ui_generator'
|
||||
|
||||
describe SwaggerRails::CustomUiGenerator do
|
||||
include GeneratorSpec::TestCase
|
||||
destination File.expand_path('../tmp', __FILE__)
|
||||
|
||||
before(:all) do
|
||||
prepare_destination
|
||||
run_generator
|
||||
end
|
||||
|
||||
it 'creates a local version of index.html.erb' do
|
||||
assert_file('app/views/swagger_rails/swagger_ui/index.html.erb')
|
||||
end
|
||||
end
|
||||
@ -7,6 +7,9 @@ describe SwaggerRails::InstallGenerator do
|
||||
|
||||
before(:all) do
|
||||
prepare_destination
|
||||
config_dir = File.expand_path('../../fixtures/config', __FILE__)
|
||||
FileUtils.cp_r(config_dir, destination_root)
|
||||
|
||||
run_generator
|
||||
end
|
||||
|
||||
@ -17,4 +20,9 @@ describe SwaggerRails::InstallGenerator do
|
||||
it 'creates a swagger_rails initializer' do
|
||||
assert_file('config/initializers/swagger_rails.rb')
|
||||
end
|
||||
|
||||
it 'wires up the swagger routes' do
|
||||
pending('not sure how to test this')
|
||||
this_should_not_get_executed
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user