transformers

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

README

Mastodon API Transformers

This package provides consolidated Mastodon API transformation utilities to eliminate the many conversion patterns scattered across the API layer.

Overview

The transformers package consolidates transformation logic that was previously duplicated across multiple files in the API layer. It provides:

  • Storage to Mastodon API transformations: Convert storage models to Mastodon API format
  • Mastodon API input to storage transformations: Convert API requests to storage format
  • Response formatting utilities: Standard response and error formatting
  • Pagination utilities: Link header generation and pagination response formatting
  • Batch processing: Efficient transformation of multiple objects
  • Caching support: Optional caching for frequently accessed transformations

Key Features

Eliminates Code Duplication

Before this consolidation, similar transformation patterns were scattered across:

  • cmd/api/handlers/helpers.go - convertStorageStatusToAPI (489 lines)
  • cmd/api/handlers/accounts_full.go - Account conversion patterns
  • cmd/api/handlers/statuses.go - Multiple status transformation calls
  • Many other API layer files with transformations. calls
Performance Optimized

Benchmark results show excellent performance:

  • Status transformation: ~3,830 ns/op
  • Account transformation: ~1,207 ns/op
  • Batch processing (100 items): ~257,199 ns/op
  • Input parameter conversion: ~42 ns/op
Integration with Existing Framework

The transformers integrate seamlessly with the existing pkg/transformations framework while providing higher-level, Mastodon-specific utilities.

Usage Examples

Basic Transformation
package main

import (
    "github.com/equaltoai/lesser/pkg/mastodon/transformers"
    storageModels "github.com/equaltoai/lesser/pkg/storage/models"
)

func handleGetStatus(ctx *lift.Context) error {
    // Get status from storage
    status := &storageModels.Status{
        StatusID:       "123",
        Content:        "Hello, world!",
        AuthorUsername: "user1",
        // ... other fields
    }
    
    // Transform to Mastodon API format
    transformer := transformers.NewMastodonTransformer("https://your-domain.com")
    mastodonStatus, err := transformer.StorageStatusToMastodon(status, "viewer_username")
    if err != nil {
        return ctx.Status(500).JSON(map[string]string{"error": err.Error()})
    }
    
    return ctx.JSON(mastodonStatus)
}
Batch Processing
func handleGetTimeline(ctx *lift.Context) error {
    // Get multiple statuses from storage
    statuses := []*storageModels.Status{
        // ... multiple status objects
    }
    
    // Process in batch for better performance
    processor := transformers.NewBatchProcessor("https://your-domain.com")
    mastodonStatuses, err := processor.ProcessStatusBatch(statuses, "viewer_username")
    if err != nil {
        return ctx.Status(500).JSON(map[string]string{"error": err.Error()})
    }
    
    return ctx.JSON(mastodonStatuses)
}
API Input Transformation
func handleCreateStatus(ctx *lift.Context) error {
    // Parse Mastodon API request
    var req models.CreateStatusRequest
    if err := ctx.ParseRequest(&req); err != nil {
        return ctx.Status(400).JSON(map[string]string{"error": "invalid request"})
    }
    
    // Transform to storage format
    transformer := transformers.NewMastodonTransformer("https://your-domain.com")
    storageReq, err := transformer.MastodonStatusParamsToStorage(&req, "author_username")
    if err != nil {
        return ctx.Status(400).JSON(map[string]string{"error": err.Error()})
    }
    
    // Use storageReq with your storage layer
    // ...
}
Response Formatting with Pagination
func handleGetAccountStatuses(ctx *lift.Context) error {
    // ... get statuses and transform them
    
    // Format paginated response
    transformer := transformers.NewMastodonTransformer("https://your-domain.com")
    
    pagination := &transformers.PaginationInfo{
        NextCursor: "next_cursor_value",
        Limit:      20,
        HasMore:    true,
    }
    
    // Set Link header
    linkHeader := transformer.BuildLinkHeader(
        "https://your-domain.com/api/v1/accounts/123/statuses", 
        pagination,
    )
    if linkHeader != "" {
        ctx.Response.Header("Link", linkHeader)
    }
    
    // Return formatted response
    response := transformer.FormatPaginatedResponse(mastodonStatuses, pagination)
    return ctx.JSON(response)
}
Error Handling
func handleAPIError(ctx *lift.Context, err error) error {
    transformer := transformers.NewMastodonTransformer("https://your-domain.com")
    errorResponse := transformer.FormatMastodonError(err)
    return ctx.Status(500).JSON(errorResponse)
}
Caching for Performance
func setupCachedTransformers() *transformers.CachedTransformer {
    cached := transformers.NewCachedTransformer("https://your-domain.com")
    
    // Cache will automatically store frequently accessed transformations
    // Clear periodically if needed:
    // cached.ClearCache()
    
    return cached
}
Integration with Transformation Framework
func useWithExistingFramework(ctx context.Context, account *storage.Account) (models.Account, error) {
    transformer := transformers.NewMastodonTransformer("https://your-domain.com")
    bridge := transformer.WithTransformationFramework()
    
    // This integrates with the existing pkg/transformations framework
    return bridge.Transform(ctx, account)
}

API Reference

Core Types
  • MastodonTransformer: Main transformer with all conversion methods
  • PaginationInfo: Pagination metadata for responses
  • StatusCreateRequest: Storage format for status creation
  • AccountUpdateRequest: Storage format for account updates
Main Methods
  • StorageStatusToMastodon(): Storage status → Mastodon API status
  • StorageAccountToMastodon(): Storage account → Mastodon API account
  • StorageNotificationToMastodon(): Storage notification → Mastodon API notification
  • MastodonStatusParamsToStorage(): API params → Storage creation request
  • MastodonAccountParamsToStorage(): API params → Storage update request
Utility Methods
  • FormatMastodonAPIResponse(): Standard API response formatting
  • FormatPaginatedResponse(): Paginated response with metadata
  • FormatMastodonError(): Standardized error responses
  • BuildLinkHeader(): RFC 5988 Link header for pagination
Augmentation Methods
  • AugmentAccountWithRelationship(): Add relationship status
  • AugmentAccountWithCounts(): Add follower/following/status counts
  • AugmentStatusWithCounts(): Add interaction counts
  • AugmentStatusWithUserInteractions(): Add user-specific flags
Batch Processing
  • BatchProcessor: Optimized batch transformation
  • ProcessStatusBatch(): Transform multiple statuses efficiently
  • ProcessAccountBatch(): Transform multiple accounts efficiently
Media and Content Processing
  • TransformStorageMediaToMastodon(): Media attachment transformation
  • TransformStorageEmojiToMastodon(): Custom emoji transformation
  • Automatic hashtag and mention formatting

Migration Guide

To migrate existing API handlers to use these transformers:

  1. Replace direct transformation calls:

    // Old way
    account := transformations.ActorToAccountBase(actor, baseURL)
    
    // New way  
    transformer := transformers.NewMastodonTransformer(baseURL)
    account, err := transformer.StorageAccountToMastodon(storageAccount)
    
  2. Consolidate response formatting:

    // Old way
    return ctx.JSON(map[string]string{"error": err.Error()})
    
    // New way
    errorResponse := transformer.FormatMastodonError(err)
    return ctx.Status(500).JSON(errorResponse)
    
  3. Use batch processing for lists:

    // Old way
    for _, status := range statuses {
        mastodonStatus := transformations.ObjectToStatusAny(status, actor, baseURL)
        results = append(results, mastodonStatus)
    }
    
    // New way
    processor := transformers.NewBatchProcessor(baseURL)
    results, err := processor.ProcessStatusBatch(statuses, viewerUsername)
    

Performance Considerations

  • Use batch processing for multiple items (3x faster than individual transforms)
  • Consider caching for frequently accessed data
  • The transformers are optimized for the most common use cases
  • Benchmark results show sub-microsecond performance for most operations

Testing

The package includes comprehensive tests and benchmarks:

go test ./pkg/mastodon/transformers/           # Run tests
go test -bench=. ./pkg/mastodon/transformers/  # Run benchmarks
go test -v ./pkg/mastodon/transformers/        # Verbose test output

Integration Points

This package is designed to work with:

  • Existing pkg/transformations framework
  • cmd/api/models Mastodon API types
  • pkg/storage and pkg/storage/models storage layer
  • pkg/activitypub ActivityPub types
  • Lift framework HTTP handlers

Future Enhancements

Potential improvements:

  • Real-time caching integration
  • Streaming transformation for large datasets
  • Additional media type support
  • Enhanced relationship status handling
  • More sophisticated error context

Documentation

Overview

Package transformers provides consolidated Mastodon API transformations for converting between storage models and Mastodon API response formats.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccountUpdateRequest

type AccountUpdateRequest struct {
	Username     string `json:"username"`
	DisplayName  string `json:"display_name,omitempty"`
	Bio          string `json:"bio,omitempty"`
	Locked       bool   `json:"locked"`
	Bot          bool   `json:"bot"`
	Discoverable bool   `json:"discoverable"`
}

AccountUpdateRequest represents a request to update an account

type BatchProcessor

type BatchProcessor struct {
	// contains filtered or unexported fields
}

BatchProcessor provides batch processing for multiple transformations

func NewBatchProcessor

func NewBatchProcessor(baseURL string) *BatchProcessor

NewBatchProcessor creates a new batch processor

func (*BatchProcessor) ProcessAccountBatch

func (bp *BatchProcessor) ProcessAccountBatch(accounts []*storage.Account) ([]*models.Account, error)

ProcessAccountBatch processes multiple accounts in batch

func (*BatchProcessor) ProcessStatusBatch

func (bp *BatchProcessor) ProcessStatusBatch(statuses []*storageModels.Status, viewerUsername string) ([]*models.Status, error)

ProcessStatusBatch processes multiple statuses in batch

type CachedTransformer

type CachedTransformer struct {
	*MastodonTransformer
	// contains filtered or unexported fields
}

CachedTransformer provides caching for frequently accessed transformations

func NewCachedTransformer

func NewCachedTransformer(baseURL string) *CachedTransformer

NewCachedTransformer creates a cached transformer

func (*CachedTransformer) ClearCache

func (ct *CachedTransformer) ClearCache()

ClearCache clears the transformation cache

type MastodonTransformer

type MastodonTransformer struct {
	// contains filtered or unexported fields
}

MastodonTransformer provides consolidated Mastodon API transformations

func NewMastodonTransformer

func NewMastodonTransformer(baseURL string) *MastodonTransformer

NewMastodonTransformer creates a new Mastodon API transformer

func (*MastodonTransformer) AugmentAccountWithCounts

func (t *MastodonTransformer) AugmentAccountWithCounts(account *models.Account, followersCount, followingCount, statusesCount int)

AugmentAccountWithCounts adds follower/following/status counts to account

func (*MastodonTransformer) AugmentAccountWithRelationship

func (t *MastodonTransformer) AugmentAccountWithRelationship(account *models.Account, relationship *models.Relationship)

AugmentAccountWithRelationship adds relationship status to account

func (*MastodonTransformer) AugmentStatusWithCounts

func (t *MastodonTransformer) AugmentStatusWithCounts(status *models.Status, repliesCount, reblogsCount, favouritesCount int)

AugmentStatusWithCounts adds interaction counts to status

func (*MastodonTransformer) AugmentStatusWithUserInteractions

func (t *MastodonTransformer) AugmentStatusWithUserInteractions(status *models.Status, favourited, reblogged, bookmarked, muted, pinned bool)

AugmentStatusWithUserInteractions adds user-specific interaction state to status

func (*MastodonTransformer) BuildLinkHeader

func (t *MastodonTransformer) BuildLinkHeader(baseURL string, pagination *PaginationInfo) string

BuildLinkHeader builds a Link header for pagination

func (*MastodonTransformer) FormatMastodonAPIResponse

func (t *MastodonTransformer) FormatMastodonAPIResponse(data interface{}) map[string]interface{}

FormatMastodonAPIResponse formats data for Mastodon API response

func (*MastodonTransformer) FormatMastodonError

func (t *MastodonTransformer) FormatMastodonError(err error) map[string]interface{}

FormatMastodonError formats an error for Mastodon API response

func (*MastodonTransformer) FormatPaginatedResponse

func (t *MastodonTransformer) FormatPaginatedResponse(items []interface{}, pagination *PaginationInfo) map[string]interface{}

FormatPaginatedResponse formats a paginated response with Link header information

func (*MastodonTransformer) MastodonAccountParamsToStorage

func (t *MastodonTransformer) MastodonAccountParamsToStorage(params *models.UpdateCredentialsRequest, username string) (*AccountUpdateRequest, error)

MastodonAccountParamsToStorage converts Mastodon account update params to storage format

func (*MastodonTransformer) MastodonStatusParamsToStorage

func (t *MastodonTransformer) MastodonStatusParamsToStorage(params *models.CreateStatusRequest, authorUsername string) (*StatusCreateRequest, error)

MastodonStatusParamsToStorage converts Mastodon status creation params to storage format

func (*MastodonTransformer) StorageAccountToMastodon

func (t *MastodonTransformer) StorageAccountToMastodon(account *storage.Account) (*models.Account, error)

StorageAccountToMastodon converts storage Account to Mastodon API Account

func (*MastodonTransformer) StorageNotificationToMastodon

func (t *MastodonTransformer) StorageNotificationToMastodon(notif *storageModels.Notification, account *models.Account, status *models.Status) (*models.Notification, error)

StorageNotificationToMastodon converts storage Notification to Mastodon API Notification

func (*MastodonTransformer) StorageStatusToMastodon

func (t *MastodonTransformer) StorageStatusToMastodon(status *storageModels.Status, _ string) (*models.Status, error)

StorageStatusToMastodon converts storage Status to Mastodon API Status

func (*MastodonTransformer) TransformStorageEmojiToMastodon

func (t *MastodonTransformer) TransformStorageEmojiToMastodon(emojis []interface{}) []interface{}

TransformStorageEmojiToMastodon converts storage emoji to Mastodon emoji format

func (*MastodonTransformer) TransformStorageMediaToMastodon

func (t *MastodonTransformer) TransformStorageMediaToMastodon(attachments []interface{}) []interface{}

TransformStorageMediaToMastodon converts storage media to Mastodon media format

func (*MastodonTransformer) WithTransformationFramework

func (t *MastodonTransformer) WithTransformationFramework() *TransformationFrameworkBridge

WithTransformationFramework enhances this transformer to work with the existing transformation framework

type PaginationInfo

type PaginationInfo struct {
	MaxID      string `json:"max_id,omitempty"`
	MinID      string `json:"min_id,omitempty"`
	SinceID    string `json:"since_id,omitempty"`
	Limit      int    `json:"limit,omitempty"`
	NextCursor string `json:"next_cursor,omitempty"`
	HasMore    bool   `json:"has_more,omitempty"`
}

PaginationInfo represents pagination metadata for Mastodon API responses

type StatusCreateRequest

type StatusCreateRequest struct {
	AuthorUsername string   `json:"author_username"`
	Content        string   `json:"content"`
	Visibility     string   `json:"visibility"`
	Sensitive      bool     `json:"sensitive"`
	Language       string   `json:"language,omitempty"`
	InReplyToID    string   `json:"in_reply_to_id,omitempty"`
	MediaIDs       []string `json:"media_ids,omitempty"`
}

StatusCreateRequest represents a request to create a status

type TransformationFrameworkBridge

type TransformationFrameworkBridge struct {
	// contains filtered or unexported fields
}

TransformationFrameworkBridge bridges this transformer with the existing transformation framework

func (*TransformationFrameworkBridge) Transform

Transform implements the Transformer interface for Account transformations

func (*TransformationFrameworkBridge) TransformList

func (tfb *TransformationFrameworkBridge) TransformList(ctx context.Context, sources []*storage.Account) ([]models.Account, error)

TransformList implements the Transformer interface for Account list transformations

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL