Skip to content

Commit

Permalink
Make camelizing of model properties configurable.
Browse files Browse the repository at this point in the history
* Fix model tag name so it is the same case as the symbol passed in. A
swagger_model :Tag was being put into the json models hash as 'tag'
instead of 'Tag'
* Created ApiDeclarationFileMetadata class to make it clear the fields
that are needed on the ApiDeclarationFile metadata object
* Updated readme
  • Loading branch information
aaronrenner committed May 28, 2014
1 parent b58a49a commit 8bbef3a
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 56 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 102,12 @@ The following table shows all the current configuration options and their defaul
<td>:pretty</td>
</tr>

<tr>
<td><b>camelize_model_properties</b></td>
<td>Camelizes property names of models. For example, a property name called first_name would be converted to firstName.</td>
<td>true</td>
</tr>

</tbody>
</table>

Expand Down Expand Up @@ -174,19 180,19 @@ end
### DRYing up common documentation

Suppose you have a header or a parameter that must be present on several controllers and methods. Instead of duplicating it on all the controllers you can do this on your API base controller:

```ruby
class Api::BaseController < ActionController::Base
class << self
Swagger::Docs::Generator::set_real_methods

def inherited(subclass)
super
subclass.class_eval do
setup_basic_api_documentation
end
end

private
def setup_basic_api_documentation
[:index, :show, :create, :update, :delete].each do |api_action|
Expand All @@ -198,7 204,7 @@ class Api::BaseController < ActionController::Base
end
end
```

And then use it as a superclass to all you API controllers. All the subclassed controllers will have the same documentation applied to them.

### DSL Methods
Expand Down
1 change: 1 addition & 0 deletions lib/swagger/docs.rb
Original file line number Diff line number Diff line change
@@ -1,5 1,6 @@
require "swagger/docs/config"
require "swagger/docs/dsl"
require "swagger/docs/api_declaration_file_metadata"
require "swagger/docs/api_declaration_file"
require "swagger/docs/generator"
require "swagger/docs/impotent_methods"
Expand Down
57 changes: 45 additions & 12 deletions lib/swagger/docs/api_declaration_file.rb
Original file line number Diff line number Diff line change
@@ -1,14 1,12 @@
module Swagger
module Docs
class ApiDeclarationFile
attr_reader :path, :apis, :models, :controller_base_path, :root
attr_reader :metadata, :apis

def initialize(path, apis, models, controller_base_path, root)
@path = path
def initialize(metadata, apis, models)
@metadata = metadata
@apis = camelize_keys_deep apis
@models = camelize_keys_deep models
@controller_base_path = controller_base_path
@root = root
@models = models
end

def generate_resource
Expand All @@ -19,15 17,27 @@ def generate_resource
end

def base_path
root["basePath"]
metadata.base_path
end

def path
metadata.path
end

def swagger_version
root["swaggerVersion"]
metadata.swagger_version
end

def api_version
root["apiVersion"]
metadata.api_version
end

def controller_base_path
metadata.controller_base_path
end

def camelize_model_properties
metadata.camelize_model_properties
end

def resource_path
Expand All @@ -38,6 48,10 @@ def resource_file_path
trim_leading_slash(debased_path.to_s.underscore)
end

def models
normalize_model_properties @models
end

private

def build_resource_root_hash
Expand All @@ -51,6 65,16 @@ def build_resource_root_hash
}
end

def normalize_model_properties(models)
Hash[
models.map do |k, v|
if camelize_model_properties
[k.to_s, camelize_keys_deep(v)]
else
[k.to_s, stringify_keys_deep(v)]
end
end]
end

def demod
"#{debased_path.to_s.camelize}".demodulize.camelize.underscore
Expand All @@ -66,22 90,31 @@ def trim_leading_slash(str)
end

def camelize_keys_deep(obj)
process_keys_deep(obj){|key| key.to_s.camelize(:lower)}
end

def stringify_keys_deep(obj)
process_keys_deep(obj){|key| key.to_s}
end

def process_keys_deep(obj, &block)
if obj.is_a? Hash
Hash[
obj.map do |k, v|
new_key = k.to_s.camelize(:lower)
new_value = camelize_keys_deep v
new_key = block.call(k)
new_value = process_keys_deep v, &block
[new_key, new_value]
end
]
elsif obj.is_a? Array
new_value = obj.collect do |a|
camelize_keys_deep a
process_keys_deep a, &block
end
else
obj
end
end

end
end
end
18 changes: 18 additions & 0 deletions lib/swagger/docs/api_declaration_file_metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 1,18 @@
module Swagger
module Docs
class ApiDeclarationFileMetadata
DEFAULT_SWAGGER_VERSION = "1.2"

attr_reader :api_version, :path, :base_path, :controller_base_path, :swagger_version, :camelize_model_properties

def initialize(api_version, path, base_path, controller_base_path, options={})
@api_version = api_version
@path = path
@base_path = base_path
@controller_base_path = controller_base_path
@swagger_version = options.fetch(:swagger_version, DEFAULT_SWAGGER_VERSION)
@camelize_model_properties = options.fetch(:camelize_model_properties, true)
end
end
end
end
10 changes: 7 additions & 3 deletions lib/swagger/docs/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 62,7 @@ def generate_doc(api_version, settings, config)
ret = process_path(path, root, config, settings)
results[ret[:action]] << ret
if ret[:action] == :processed
resources << generate_resource(ret[:path], ret[:apis], ret[:models], settings, root)
resources << generate_resource(ret[:path], ret[:apis], ret[:models], settings, root, config)
debased_path = get_debased_path(ret[:path], settings[:controller_base_path])
resource_api = {
path: "#{Config.transform_path(trim_leading_slash(debased_path))}.{format}",
Expand Down Expand Up @@ -132,8 132,12 @@ def process_path(path, root, config, settings)
{action: :processed, path: path, apis: apis, models: models, klass: klass}
end

def generate_resource(path, apis, models, settings, root)
declaration = ApiDeclarationFile.new(path, apis, models, settings[:controller_base_path], root)
def generate_resource(path, apis, models, settings, root, config)
metadata = ApiDeclarationFileMetadata.new(root["apiVersion"], path, root["basePath"],
settings[:controller_base_path],
camelize_model_properties: config.fetch(:camelize_model_properties, true),
swagger_version: root["swaggerVersion"])
declaration = ApiDeclarationFile.new(metadata, apis, models)
declaration.generate_resource
end

Expand Down
55 changes: 55 additions & 0 deletions spec/lib/swagger/docs/api_declaration_file_metadata_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 1,55 @@
require 'spec_helper'

describe Swagger::Docs::ApiDeclarationFileMetadata do

describe "#initialize" do
it "sets the api_version property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.api_version).to eq("1.0")
end

it "sets the path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.path).to eq("path")
end

it "sets the base_path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.base_path).to eq("basePath")
end

it "sets the controller_base_path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.controller_base_path).to eq("controllerBasePath")
end

it "defaults the swagger_version property to DEFAULT_SWAGGER_VERSION" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.swagger_version).to eq(described_class::DEFAULT_SWAGGER_VERSION)
end

it "allows the swagger_version property to be_overriden" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath", swagger_version: "2.0")

expect(metadata.swagger_version).to eq("2.0")
end


it "defaults the camelize_model_properties property to true" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.camelize_model_properties).to eq(true)
end

it "allows the camelize_model_properties property to be overidden" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath", camelize_model_properties: false)

expect(metadata.camelize_model_properties).to eq(false)
end
end
end
Loading

0 comments on commit 8bbef3a

Please sign in to comment.