Skip to content

zio-blocks-ops-mirror: OpsMirror type class for trait method introspection #1143

@987Nabil

Description

@987Nabil

Summary

Add an OpsMirror module (zio-blocks-ops-mirror) providing compile-time introspection of trait methods, analogous to how scala.deriving.Mirror works for case classes/enums but for service traits with operations.

Motivation

For zio-http 4.0's service framework, we need the ability to derive typed endpoint providers, route generators, OpenAPI specs, and client proxies from a Scala trait definition like:

trait TodoService derives EndpointProvider:
  @GET("/todos/{id}")
  def getTodo(id: Int): Todo

  @POST("/todos")
  def createTodo(todo: CreateTodo): Todo

This requires a compile-time mirror that captures:

  • Method names (operation labels)
  • Parameter names, types, and bindings (path, query, header, body)
  • Return types (including effect wrappers)
  • HTTP annotations (method, path pattern)
  • Documentation annotations

`scala.deriving.Mirror` only works for product/sum types (case classes, enums), NOT for traits with methods. We need a custom `OpsMirror` that fills this gap.

Design Sketch

trait OpsMirror:
  type MirroredType
  type OperationLabels <: Tuple     // ("getTodo", "createTodo", ...)
  type Operations <: Tuple          // Tuple of Operation refined types

object OpsMirror:
  type Of[T] = OpsMirror { type MirroredType = T }

  trait Operation:
    type InputTypes <: Tuple
    type InputLabels <: Tuple
    type OutputType
    type ErrorType
    type HttpMethod
    type PathPattern
    type InputBindings <: Tuple

This is placed in zio-blocks (not zio-http) because:

  • It's a general-purpose trait introspection mechanism
  • It can be used for RPC, gRPC, GraphQL, or any protocol — not just HTTP
  • It depends only on Scala standard library types (Tuple, etc.)
  • Service framework consumers (EndpointProvider, RoutesProvider) live in zio-http and USE OpsMirror, but the mirror itself is protocol-agnostic

Scala Version Strategy

  • Scala 3: inline given derived using quoted macros to inspect trait methods
  • Scala 2.13: Whitebox macro that generates the equivalent type information

Prior Art

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions