Class: Steppe::Serializer

Inherits:
Object
  • Object
show all
Extended by:
Plumb::Composable
Includes:
Plumb::Attributes
Defined in:
lib/steppe/serializer.rb

Overview

Note:

Serializers automatically generate attribute reader methods that delegate to the @object instance variable (the response data)

Note:

The #result method provides access to the full Result context including request, params, errors, and response data

Note:

Type definitions support .example() for OpenAPI documentation generation

Base class for response serialization in Steppe endpoints.

Serializers transform response data into structured output using Plumb types and attributes. They provide a declarative way to define the structure of response bodies with type validation and examples for OpenAPI documentation.

Examples:

Basic serializer for a user resource

class UserSerializer < Steppe::Serializer
  attribute :id, Types::Integer.example(1)
  attribute :name, Types::String.example('Alice')
  attribute :email, Types::Email.example('[email protected]')

  # Optional: custom attribute methods
  def name
    object.full_name.titleize
  end
end

Nested serializers and arrays

class UserListSerializer < Steppe::Serializer
  attribute :users, [UserSerializer]
  attribute :count, Types::Integer
  attribute :page, Types::Integer.default(1)

  def users
    object # Assuming object is an array of user objects
  end

  def count
    object.size
  end
end

Error response serializer

class ErrorSerializer < Steppe::Serializer
  attribute :errors, Types::Hash.example({ 'name' => 'is required' })
  attribute :message, Types::String.example('Validation failed')

  def errors
    result.errors
  end

  def message
    'Request validation failed'
  end
end

Using in endpoint responses

api.get :users, '/users' do |e|
  e.step do |conn|
    users = User.all
    conn.valid(users)
  end

  # Using a predefined serializer class
  e.serialize 200, UserListSerializer

  # Using inline serializer definition
  e.serialize 404 do
    attribute :error, String
    def error = 'Users not found'
  end
end

Accessing result context

class UserWithMetaSerializer < Steppe::Serializer
  attribute :user, UserSerializer
  attribute :request_id, String

  def user
    object
  end

  def request_id
    result.request.env['HTTP_X_REQUEST_ID'] || 'unknown'
  end
end

See Also:

Direct Known Subclasses

Endpoint::DefaultEntitySerializer

Constant Summary collapse

RenderError =
Class.new(StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(result) ⇒ Serializer

Initialize a new serializer instance.

Parameters:

  • result (Result)

    The result object containing the value to serialize and full request context



142
143
144
145
# File 'lib/steppe/serializer.rb', line 142

def initialize(result)
  @result = result
  @object = result.value
end

Instance Attribute Details

#objectObject (readonly)

Returns the value of attribute object.



# File 'lib/steppe/serializer.rb', line 131

#resultObject (readonly)

Returns the value of attribute result.



136
# File 'lib/steppe/serializer.rb', line 136

attr_reader :object, :result

Class Method Details

.__plumb_define_attribute_reader_method__(name) ⇒ Object

Serialize an object using this serializer class.

Internal method that defines attribute reader methods. Automatically creates methods that delegate to @object.attribute_name



103
104
105
106
107
# File 'lib/steppe/serializer.rb', line 103

def __plumb_define_attribute_reader_method__(name)
  class_eval <<~RUBY, __FILE__, __LINE__ + 1
  def #{name} = @object.#{name}
  RUBY
end

.call(conn) ⇒ Result

Internal method called during endpoint processing to serialize results.

Parameters:

  • conn (Result)

    The result object containing the value to serialize

Returns:

  • (Result)

    New result with serialized value



125
126
127
128
# File 'lib/steppe/serializer.rb', line 125

def call(conn)
  hash = new(conn).serialize
  conn.copy(value: hash)
end

.render(conn) ⇒ String?

Returns JSON string of serialized value or nil if no value.

Parameters:

  • conn (Result)

    The result object containing the value to serialize

Returns:

  • (String, nil)

    JSON string of serialized value or nil if no value

Raises:



113
114
115
116
117
118
# File 'lib/steppe/serializer.rb', line 113

def render(conn)
  result = call(conn)
  raise RenderError, result.errors if result.invalid?

  result.value ? JSON.dump(result.value) : nil
end

Instance Method Details

#connObject



147
# File 'lib/steppe/serializer.rb', line 147

def conn = result

#serializeHash

Serialize the object to a hash using defined attributes.

Iterates through all defined attributes, calls the corresponding method (either auto-generated or custom), and applies the attribute’s type transformation and validation.

Examples:

serializer = UserSerializer.new(result)
serializer.serialize
# => { id: 1, name: "Alice", email: "[email protected]" }

Returns:

  • (Hash)

    The serialized hash with symbol keys



160
161
162
163
164
# File 'lib/steppe/serializer.rb', line 160

def serialize
  self.class._schema._schema.each.with_object({}) do |(key, type), ret|
    ret[key.to_sym] = serialize_attribute(key.to_sym, type)
  end
end

#serialize_attribute(key, type) ⇒ Object

Serialize a single attribute using its defined type.

Examples:

serialize_attribute(:name, Types::String)
# => "Alice"

Parameters:

  • key (Symbol)

    The attribute name

  • type (Plumb::Type)

    The Plumb type definition for the attribute

Returns:

  • (Object)

    The serialized attribute value



174
175
176
177
178
# File 'lib/steppe/serializer.rb', line 174

def serialize_attribute(key, type)
  # Ex. value = self.name
  value = send(key)
  type.call(result.copy(value:)).value
end