DEV Community

Cover image for MonkeysLegion GraphQL 2.0 — A Complete Rewrite, Built for the Future
Jorge Peraza
Jorge Peraza

Posted on

MonkeysLegion GraphQL 2.0 — A Complete Rewrite, Built for the Future

When I started working on MonkeysLegion GraphQL, the goal was simple:
Make GraphQL feel native to modern PHP.

Version 2.0 is not an upgrade.
It's a complete architectural rewrite.

👉 Repo: MonkeysLegion-GraphQL


Why a Complete Rewrite?

GraphQL in PHP often feels:

  • Too coupled to webonyx
  • Configuration-heavy
  • Reflection-expensive
  • Hard to secure properly
  • Difficult to scale for real production workloads

So instead of patching the old system… I rebuilt it from scratch.


What's New in 2.0

🧩 Attribute-Driven Schema Definition

No more schema arrays. No more manual wiring.
Everything is powered by PHP 8.4 attributes.

#[Type]
class UserType
{
    #[Field]
    public function id(): int {}

    #[Field]
    public function name(): string {}
}

#[Query]
class UserQuery
{
    #[Field]
    public function user(#[Arg] int $id): User {}
}
Enter fullscreen mode Exit fullscreen mode

Supported attributes:

#[Type] · #[Field] · #[Query] · #[Mutation] · #[Subscription] · #[Arg] · #[InputType] · #[Enum] · #[InterfaceType] · #[UnionType] · #[Middleware]

Clean. Typed. Explicit.


⚙️ New Architecture (Builder Pipeline)

The entire schema generation system is now modular:

  • SchemaBuilder
  • TypeBuilder
  • FieldBuilder
  • InputTypeBuilder
  • EnumBuilder
  • ArgumentBuilder

No magic factory classes. No static schema definitions. Just a clean build pipeline.


🧠 GraphQLContext (Immutable Execution Context)

Every request now gets an immutable execution context — HTTP request, authenticated user, DI container, and DataLoaderRegistry:

$context = new GraphQLContext(
    request: $request,
    user: $user,
    container: $container
);
Enter fullscreen mode Exit fullscreen mode

Predictable. Safe. Testable.


🚀 Performance: DataLoader + Batch Execution

DataLoader — per-request caching + batching. No more N+1 query nightmares.

abstract class DataLoader {
    abstract protected function batchLoad(array $keys): array;
}
Enter fullscreen mode Exit fullscreen mode
  • Per-request caching
  • Batch loading
  • Registry-based resolution

BatchExecutor — supports multiple operations in one request. Useful for complex clients, microfrontend architectures, and optimized API gateways.


🔒 Security Built-In

Security is not optional anymore. MonkeysLegion GraphQL 2.0 includes:

  • DepthLimiter
  • ComplexityAnalyzer
  • IntrospectionControl
  • PersistedQueries
  • RateLimiter

Production-ready from day one.


🧱 Custom Scalars Included

Out of the box support for: DateTime · JSON · Email · URL · Upload

No need to reimplement common scalars.


🔄 Subscriptions (Modern Protocol)

WebSocket layer completely rewritten.

❌ Removed subscriptions-transport-ws
✅ Now using graphql-ws

New components:

  • SubscriptionServer
  • SubscriptionManager
  • PubSubInterface
  • InMemoryPubSub / RedisPubSub
  • WsAuthenticator

Removed heavy dependencies like Ratchet/React. Cleaner. Faster. Modern.


🗂 Schema Caching (PSR-16)

Reflection is expensive. So we cache it.

  • SchemaCache
  • SchemaCacheWarmer

CLI commands:

php mlc graphql:cache:warm
php mlc graphql:cache:clear
Enter fullscreen mode Exit fullscreen mode

Zero-runtime schema rebuilds in production.


🧾 Input Validation System

Built-in validation layer with InputValidator and RuleSet. Structured validation errors via ValidationError and AuthorizationError.

No need to plug external validation unless you want to.


🔌 PSR-15 Middleware Support

Fully PSR-15 compatible:

  • GraphQLMiddleware
  • GraphiQLMiddleware
  • UploadMiddleware

Drop into any modern PHP stack.


🧬 Entity Integration

Native support for mapping domain entities via EntityTypeMapper and EntityResolver.

Makes MonkeysLegion's entity system work seamlessly with GraphQL.


🔗 Relay Pagination Support

ConnectionType · EdgeType · PageInfoType

Ready for modern frontend clients.


🧰 CLI Tooling

Built-in CLI commands:

  • graphql:schema:dump
  • graphql:schema:validate
  • graphql:cache:warm
  • graphql:cache:clear
  • graphql:introspect

GraphQL now feels like a first-class framework citizen.


⚠️ Breaking Changes

This is version 2.0 for a reason.

Changed:

What Before → After
Minimum PHP version 8.4
WebSocket protocol graphql-ws
Configuration .mlc files (typed)
Types No longer extend webonyx base classes

Removed:

  • Schema\SchemaFactory
  • Support\Scanner
  • Execution\Executor
  • WebSocket\WsHandler
  • Ratchet/React dependencies

Everything replaced with cleaner architecture.


Why This Matters

This release is about performance, security, modern PHP design, clean architecture, and production-readiness.

It's not just "GraphQL working in PHP."
It's GraphQL designed for serious applications.


What's Next?

  • Federation support
  • Advanced query cost modeling
  • Observability hooks
  • Native OpenTelemetry integration
  • Extended subscription drivers

Final Thoughts

MonkeysLegion GraphQL 2.0 is the foundation for everything I'm building next — AI-native CMS (MonkeysCMS), scalable SaaS APIs, real-time systems, and high-performance microservices.

Rewriting it was painful. But worth it.

If you're building serious PHP applications and want modern GraphQL done right:

👉 MonkeysLegion-GraphQL on GitHub

Top comments (0)