Documentation for LLMs on building APIs with the Apia framework
Polymorphs allow a single field to return different object types based on runtime conditions. This is useful when a field could contain one of several related but distinct types.
module MyAPI
module Objects
class EventSubject < Apia::Polymorph
name "Event Subject"
description "The subject of an event (could be a user, organization, or server)"
option :user, type: Objects::User, matcher: -> (value) { value.is_a?(::User) }
option :organization, type: Objects::Organization, matcher: -> (value) { value.is_a?(::Organization) }
option :server, type: Objects::Server, matcher: -> (value) { value.is_a?(::Server) }
end
end
end
option(name, type:, matcher:)Adds a polymorph option. Each option defines:
name - A symbol identifying this optiontype: - The object type (or scalar/enum) to serialize the value asmatcher: - A lambda that returns true if the given value should use this optionoption :user, type: Objects::User, matcher: -> (value) { value.is_a?(::User) }
option :organization, type: Objects::Organization, matcher: -> (value) { value.is_a?(::Organization) }
Reference the polymorph type on a field:
class Event < Apia::Object
field :subject, Objects::EventSubject
end
When a polymorph field is serialized, the response includes the matched type name and the serialized value:
{
"subject": {
"type": "user",
"value": {
"id": "abc-123",
"name": "John Doe",
"email": "john@example.com"
}
}
}
matcher lambda with the actual valueInvalidPolymorphValueError is raisedclass UserObject < Apia::Object
field :id, :string
field :name, :string
field :email, :string
end
class TeamObject < Apia::Object
field :id, :string
field :name, :string
field :member_count, :integer
end
class Assignable < Apia::Polymorph
name "Assignable"
description "Something that can be assigned to a task"
option :user, type: UserObject, matcher: -> (v) { v.is_a?(::User) }
option :team, type: TeamObject, matcher: -> (v) { v.is_a?(::Team) }
end
class Task < Apia::Object
field :id, :string
field :title, :string
field :assignee, Assignable, null: true
end