Files
openfoodnetwork/app/json_schemas/json_api_schema.rb
2022-03-02 11:59:35 +11:00

115 lines
2.5 KiB
Ruby

# frozen_string_literal: true
class JsonApiSchema
class << self
def attributes
{}
end
def required_attributes
[]
end
def relationships
[]
end
def all_attributes
attributes.keys
end
def schema(options = {})
{
type: :object,
properties: {
data: {
type: :object,
properties: data_properties(**options)
},
meta: { type: :object },
links: { type: :object }
},
required: [:data]
}
end
def collection(options)
{
type: :object,
properties: {
data: {
type: :array,
items: {
type: :object,
properties: data_properties(**options)
}
},
meta: {
type: :object,
properties: {
pagination: {
type: :object,
properties: {
results: { type: :integer, example: 250 },
pages: { type: :integer, example: 5 },
page: { type: :integer, example: 2 },
per_page: { type: :integer, example: 50 },
}
}
},
required: [:pagination]
},
links: {
type: :object,
properties: {
self: { type: :string },
first: { type: :string },
prev: { type: :string, nullable: true },
next: { type: :string, nullable: true },
last: { type: :string }
}
}
},
required: [:data, :meta, :links]
}
end
private
def data_properties(require_all: false)
required = require_all ? all_attributes : required_attributes
{
id: { type: :string, example: "1" },
type: { type: :string, example: object_name },
attributes: {
type: :object,
properties: attributes,
required: required
},
relationships: {
type: :object,
properties: relationships.to_h do |name|
[
name,
relationship_schema(name)
]
end
}
}
end
def relationship_schema(name)
if is_singular?(name)
RelationshipSchema.schema(name)
else
RelationshipSchema.collection(name)
end
end
def is_singular?(name)
name.to_s.singularize == name.to_s
end
end
end