mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
115 lines
2.5 KiB
Ruby
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
|