Skip to content

feat: Add directive layer#807

Open
michael-georgiadis wants to merge 6 commits into
thecodingmachine:masterfrom
michael-georgiadis:feat/graphql-directive-layer
Open

feat: Add directive layer#807
michael-georgiadis wants to merge 6 commits into
thecodingmachine:masterfrom
michael-georgiadis:feat/graphql-directive-layer

Conversation

@michael-georgiadis
Copy link
Copy Markdown

Description

As per your comment on this PR, I am splitting the implementation into two.

I am focusing on configuring the directive layer on this one. Specifying two directives to start with.

How it works

A directive is a PHP attribute implementing one of the family interfaces, which ties it to a GraphQL location (FieldDirectiveFIELD_DEFINITION, InputObjectTypeDirectiveINPUT_OBJECT, etc.). Implementing the marker interface alone is metadata-only; implementing the matching Behavioral* sub-interface adds an apply hook that runs through a middleware pipe during type generation.

The built-ins on the layer

  • #[OneOf] → sets webonyx's isOneOf flag → prints input LookupInput @oneOf.
  • #[Deprecated(reason:)] → sets the field's deprecation reason → prints
    legacy: String! @deprecated(reason: "...").

Both bind to directives webonyx already declares, so they print through webonyx's own SDL output and we don't register duplicate definitions for them (DirectiveDefinition::$builtIn).

@deprecated: additive, not a rewrite

The existing docblock @deprecated support is untouched. #[Deprecated] is an attribute-based
path that composes with it rather than fighting it:

Declaration Result
#[Deprecated(reason: 'X')] (± docblock) @deprecated(reason: "X") — explicit wins
#[Deprecated] + /** @deprecated Y */ @deprecated(reason: "Y") — docblock kept
#[Deprecated], no docblock @deprecated(reason: "No longer supported") — default

Usage validation

PHP's #[Attribute] targets can't tell a #[Type] class from an #[Input] class (both are TARGET_CLASS), so a misplaced #[OneOf] on a #[Type] would otherwise be silently dropped by the interface-based collection. DirectiveValidator catches that and throws a clear InvalidDirectiveException instead.

@michael-georgiadis michael-georgiadis changed the title Feat/graphql directive layer feat: Add directive layer Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant