Skip to content

Instantly share code, notes, and snippets.

@robertomiranda
Last active February 18, 2021 16:52
Show Gist options
  • Save robertomiranda/45007f2958637a6ec74ae8441ca96584 to your computer and use it in GitHub Desktop.
Save robertomiranda/45007f2958637a6ec74ae8441ca96584 to your computer and use it in GitHub Desktop.
require "json"
require "time"
module HashToOpenApiSchema
def self.get_type(value)
Time.parse(value)
"date-time"
rescue
case value
when TrueClass
"boolean"
when FalseClass
"boolean"
else
value.class.name.downcase
end
end
def self.array_schema(values)
values.map do |value|
type = get_type(value)
schema_main_body(type, value)
end
end
def self.schema_main_body(type, example)
{
type: type,
description: "DESCRIPTION GOES HERE",
example: example
}
end
def self.generic_schema(hash, output = {})
hash.each do |key, value|
type = get_type(value)
case type
when "hash"
output[key] = { properties: generic_schema(value) }
output[key].merge!(schema_main_body("object", value))
when "array"
output[key] = { items: array_schema(value) }
output[key].merge!(schema_main_body(type, value))
else
output[key] = schema_main_body(type, value)
output[key].merge!(enum: [value]) if key == "type"
end
end
output
end
def self.run(hash)
generic_schema = generic_schema(hash)
json_schema = {
required: hash.keys,
type: "object",
properties: generic_schema,
example: hash
}
end
end
payload = {"type"=>"bookmark_with_cooksnap_comments",
"id"=>1,
"visited_at"=>"2021-01-28T17:11:25Z",
"recipe"=> { title: "title", bookmark_ids: [1,"2",true] }
}
puts JSON.pretty_generate(HashToOpenApiSchema.run(payload))
{
"required": [
"type",
"id",
"visited_at",
"recipe"
],
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "DESCRIPTION GOES HERE",
"example": "bookmark_with_cooksnap_comments",
"enum": [
"bookmark_with_cooksnap_comments"
]
},
"id": {
"type": "integer",
"description": "DESCRIPTION GOES HERE",
"example": 1
},
"visited_at": {
"type": "date-time",
"description": "DESCRIPTION GOES HERE",
"example": "2021-01-28T17:11:25Z"
},
"recipe": {
"properties": {
"title": {
"type": "string",
"description": "DESCRIPTION GOES HERE",
"example": "title"
},
"bookmark_ids": {
"items": [
{
"type": "integer",
"description": "DESCRIPTION GOES HERE",
"example": 1
},
{
"type": "string",
"description": "DESCRIPTION GOES HERE",
"example": "2"
},
{
"type": "boolean",
"description": "DESCRIPTION GOES HERE",
"example": true
}
],
"type": "array",
"description": "DESCRIPTION GOES HERE",
"example": [
1,
"2",
true
]
}
},
"type": "object",
"description": "DESCRIPTION GOES HERE",
"example": {
"title": "title",
"bookmark_ids": [
1,
"2",
true
]
}
}
},
"example": {
"type": "bookmark_with_cooksnap_comments",
"id": 1,
"visited_at": "2021-01-28T17:11:25Z",
"recipe": {
"title": "title",
"bookmark_ids": [
1,
"2",
true
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment