Skip to content

Conversation

@jhollinger
Copy link
Contributor

@jhollinger jhollinger commented Oct 24, 2025

A greatly simplified extension structure based around middleware instead of hooks. The extension system is comprised of multiple "stacks" of middlewares. A "render" fires off a nested call structure of these stacks:

around_result
  around_blueprint_init # only on first pass
    around_serialize_object | around_serialize_collection
      around_blueprint
        around_field_value | around_object_value | around_collection_value

Much like in Rack, each middleware receives a "context" and may choose to modify it before yielding to the next middleware. The yield returns the response, which the middleware may modify before returning. A middleware may choose not to yield at all and return a response of its choosing (e.g. a caching layer).

# Runs every time an object is serialized
def around_blueprint(ctx)
  # replace or modify the object being serialized
  ctx.object = modify ctx.object

  # yield to the next middleware or Blueprinter core
  result = yield ctx

  # Wrap the result before handing it to the previous middleware's yield or Blueprinter core
  { data: result }
end

Instead of specialized hooks like field_value, exclude_field?, and field_result, a single around_field_value hook can be used for anything relating to a field's value:

def around_field_value(ctx)
  val = yield ctx
  if ctx.options[:skip_on] && val == ctx.options[:skip_on]
    # calling skip will abort the whole stack and cause the field to be ignored
    # this is how if/unless/etc are now implemented
    skip
  else
    val
  end
end

@jhollinger jhollinger self-assigned this Oct 24, 2025
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch 3 times, most recently from 89c7e59 to 085c5dc Compare October 24, 2025 15:52
@jhollinger jhollinger changed the title Rack-inspired hooks for V2 V2 Extensions as middleware Oct 26, 2025
@jhollinger jhollinger changed the title V2 Extensions as middleware V2 Extensions as Middleware Oct 26, 2025
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch 11 times, most recently from 380635f to cf8a28c Compare October 28, 2025 16:24
@jhollinger jhollinger marked this pull request as ready for review October 28, 2025 16:27
@jhollinger jhollinger requested review from a team and ritikesh as code owners October 28, 2025 16:27
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch 2 times, most recently from 0bb37ea to 20c1304 Compare October 28, 2025 17:29
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch from 20c1304 to cbe9716 Compare October 30, 2025 13:14
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch from e2b6fc0 to 16ff30b Compare November 11, 2025 21:15
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch 5 times, most recently from 45dd30d to 50f0f8b Compare November 14, 2025 21:19
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch from 50f0f8b to cf0c5b5 Compare November 14, 2025 23:28
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
Signed-off-by: Jordan Hollinger <jordan.hollinger@procore.com>
@jhollinger jhollinger force-pushed the jh/rack-inspired-hooks branch from 1df3087 to 0c7470d Compare November 19, 2025 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants