Documentation Generation - mtkachenk0/paradocs GitHub Wiki

#structure

A Schema instance has a #structure method that allows instrospecting schema meta data.

create_user_schema.structure[:name][:label] # => "User's full name"
create_user_schema.structure[:age][:label] # => "User's age"
create_user_schema.structure[:friends][:label] # => "User friends"
# Recursive schema structures
create_user_schema.structure => {
  _errors: [],
  _subschemes: {},
  name: {
    required: true,
    type: :string,
    label: "User's full name"
  },
  status: {
    options: ["published", "unpublished"],
    default: "published"
  },
  age: {
    type: :integer,
    label: "User's age"
  },
  friends: {
    type: :array,
    label: "User friends",
    structure: {
      _subschemes: {},
      name: {
        type: :string,
        required: true,
        present: true,
        label: "Friend full name"
      },
      email: {label: "Friend's email"}
    }
  }
}

Note that many field policies add field meta data.

create_user_schema.structure[:name][:type] # => :string
create_user_schema.structure[:name][:required] # => true
create_user_schema.structure[:status][:options] # => ["published", "unpublished"]
create_user_schema.structure[:status][:default] # => "published"

#flatten_structure

A Schema instance also has a #flatten_structure method that allows instrospecting schema meta data without deep nesting.

{
  _errors: [],
  _subschemes: {},
  "name"=>{
    required: true,
    type: :string,
    label: "User's full name",
    json_path: "$.name"
  },
  "status"=>{
    options: ["published", "unpublished"],
    default: "published",
    json_path: "$.status"
  },
  "age"=>{
    type: :integer,
    label: "User's age", :json_path=>"$.age"
  },
  "friends"=>{
    type: :array,
    label: "User friends",
    json_path: "$.friends"
  },
  "friends.name"=>{
    type: :string,
    required: true,
    present: true,
    label: "Friend full name",
    json_path: "$.friends.name"
  },
  "friends.email"=>{
    label: "Friend's email",
    json_path: "$.friends.email"
  }
}

#walk

The #walk method can recursively walk a schema definition and extract meta data or field attributes.

schema_documentation = create_user_schema.walk do |field|
  {type: field.meta_data[:type], label: field.meta_data[:label]}
end.output

# Returns

{
  name: {type: :string, label: "User's full name"},
  age: {type: :integer, label: "User's age"},
  status: {type: :string, label: nil},
  friends: [
    {
      name: {type: :string, label: "Friend full name"},
      email: {type: nil, label: "Friend email"}
    }
  ]
}

When passed a symbol, it will collect that key from field meta data.

schema_labels = create_user_schema.walk(:label).output

# returns

{
  name: "User's full name",
  age: "User's age",
  status: nil,
  friends: [
    {name: "Friend full name", email: "Friend email"}
  ]
}

Potential uses for this are generating documentation (HTML, or JSON Schema, Swagger, or maybe even mock API endpoints with example data.