rebing/graphql-laravel
Code-first GraphQL integration for Laravel built on webonyx/graphql-php. Define schema in PHP (types, queries, mutations), support multiple schemas with per-schema middleware, resolver middleware, privacy rules, and data loading to avoid N+1 (dataloaders/SelectFields).
## Technical Evaluation
### **Architecture Fit**
- **Code-First GraphQL**: Aligns perfectly with Laravel’s PHP-centric ecosystem, eliminating the need for `.graphql` schema files. The package leverages PHP classes for types, queries, and mutations, making it intuitive for Laravel developers already familiar with Eloquent models and service classes.
- **Schema Flexibility**: Supports **multiple schemas** (e.g., `default`, `admin`, `public`), each with isolated queries, mutations, types, and middleware. This is ideal for **microservices, multi-tenancy, or role-based APIs** where different schemas require distinct access controls or data structures.
- **Middleware Layers**:
- **Execution Middleware**: Intercepts the entire GraphQL pipeline (e.g., auth, validation, persisted queries). Useful for **cross-cutting concerns** like rate limiting, logging, or OpenTelemetry tracing.
- **Resolver Middleware**: Wraps individual field resolvers (e.g., caching, auditing). Enables **fine-grained control** over data resolution (e.g., logging failed queries or injecting context).
- **Data Loading Strategies**:
- **Dataloaders**: Built-in deferred resolution to **batch and cache database queries**, mitigating the N+1 problem. Compatible with Eloquent, databases, or external APIs.
- **SelectFields (Optional)**: Analyzes GraphQL queries to optimize Eloquent `select()` and `with()` calls, reducing over-fetching. Critical for **performance-sensitive APIs** with complex relationships.
### **Integration Feasibility**
- **Laravel Native**: Designed for Laravel 12/13, with **zero configuration** for basic use cases. Leverages Laravel’s **service container, facades, and artisan commands** (e.g., `make:graphql:type`).
- **Eloquent Integration**: Seamlessly maps GraphQL types to Eloquent models. The `rebing/graphql-laravel-select-fields` package further optimizes database queries by aligning `select()` clauses with GraphQL fields.
- **Validation**: Native Laravel validation rules (e.g., `required`, `email`) can be applied to GraphQL arguments, reducing boilerplate for input validation.
- **Authorization**: Built-in `authorize()` methods on queries/mutations/types enable **role-based access control (RBAC)** or attribute-level permissions (e.g., `@can` directives).
### **Technical Risk**
- **Learning Curve**: Requires familiarity with **GraphQL concepts** (schema design, resolvers, types) and Laravel’s service container. Teams new to GraphQL may need **training or documentation** to adopt this effectively.
- **Performance Overhead**:
- **Introspection**: Disabled by default (security best practice) but required for GraphiQL/IDE tooling. Must be **explicitly enabled** in production.
- **Complexity Analysis**: Query depth/complexity limits must be **configured manually** to prevent abuse (e.g., denial-of-service via deeply nested queries).
- **Dataloaders**: While efficient, improper use (e.g., unbounded batch sizes) can **degrade performance**. Requires monitoring and tuning.
- **Subscriptions Limitation**: **No built-in subscriptions** (unlike Lighthouse). Real-time features require **separate implementations** (e.g., Laravel Echo + Pusher).
- **Optional Dependencies**: Packages like `mll-lab/laravel-graphiql` (for IDE support) or `open-telemetry/api` (for tracing) add **indirect complexity** to the stack.
### **Key Questions**
1. **Schema Design**:
- How will schemas be **partitioned** (e.g., by tenant, feature flag, or API version)? Will multiple schemas introduce **maintenance overhead**?
- Are **custom scalars** (e.g., JSON, UUID) needed? The package supports them but requires manual implementation.
2. **Performance**:
- Will **query complexity analysis** be enabled? How will limits be set to balance flexibility and security?
- Are **Dataloaders** sufficient for the expected query patterns, or will `SelectFields` be required for Eloquent optimizations?
3. **Security**:
- How will **introspection** be managed in production (disabled vs. rate-limited)?
- Are there **sensitive fields** requiring fine-grained authorization? The `Privacy` system supports this but may need customization.
4. **Tooling**:
- Will **GraphiQL** or **Apollo Studio** be used for development? If so, ensure introspection and IDE support are configured.
- Are **automatic persisted queries** needed to reduce payload size and improve caching?
5. **Testing**:
- How will GraphQL endpoints be **tested** (unit vs. integration)? The package provides `TestCase` and `TestCaseDatabase` bases for PHPUnit.
- Are **mutation tests** critical? The package supports testing with variables and error assertions.
---
## Integration Approach
### **Stack Fit**
- **Laravel 12/13**: Native support with **zero breaking changes** for core Laravel features (routes, middleware, service container).
- **PHP 8.2+**: Leverages modern PHP features (e.g., named arguments, attributes) for cleaner code.
- **Eloquent**: Optimized for Eloquent models with **SelectFields** for query optimization. Works with raw queries or repositories.
- **Validation**: Integrates with Laravel’s **Validator** for argument validation, reducing duplication.
- **Middleware**: Reuses Laravel’s **HTTP middleware** pipeline for GraphQL endpoints (e.g., auth, CORS).
- **Observability**: Supports **OpenTelemetry** for distributed tracing, aligning with modern observability stacks.
### **Migration Path**
1. **Assessment Phase**:
- Audit existing REST endpoints to identify **candidate GraphQL queries/mutations**.
- Define **schema boundaries** (e.g., `default`, `admin`) based on access control or feature separation.
2. **Incremental Adoption**:
- Start with **non-critical endpoints** (e.g., read-only queries) to validate performance and developer experience.
- Use `make:graphql:type` and `make:graphql:query` to scaffold types and resolvers.
- Gradually migrate **write operations** (mutations) as confidence grows.
3. **Performance Optimization**:
- Enable **Dataloaders** for N+1 queries early.
- Add `SelectFields` if Eloquent queries are inefficient.
- Configure **query complexity limits** to prevent abuse.
4. **Tooling Setup**:
- Install `mll-lab/laravel-graphiql` for development IDE support.
- Enable **persisted queries** if client-side caching is a priority.
5. **Deprecation Strategy**:
- Use GraphQL’s **deprecation system** to phase out REST endpoints.
- Version schemas (e.g., `v1`, `v2`) to support parallel development.
### **Compatibility**
- **Existing Laravel Features**:
- **Authentication**: Works with Laravel’s auth (e.g., `Auth::user()` in resolvers).
- **Middleware**: Supports Laravel middleware on GraphQL routes (e.g., `auth:api`).
- **Events**: Can dispatch Laravel events from resolvers (e.g., `event(new ModelCreated($model))`).
- **Jobs/Queues**: Resolvers can dispatch Laravel jobs for async processing.
- **Third-Party Packages**:
- **Lighthouse**: Not a replacement but can coexist for subscriptions.
- **Nova/Vue**: GraphQL types can mirror Nova resources or Vuex stores.
- **API Platform**: Can serve as an alternative to API Platform’s GraphQL bundle.
### **Sequencing**
1. **Setup**:
- Install the package: `composer require rebing/graphql-laravel`.
- Publish config: `php artisan vendor:publish --provider="Rebing\GraphQL\GraphQLServiceProvider"`.
- Configure `config/graphql.php` (schemas, middleware, security).
2. **Core Schema**:
- Define **types** (e.g., `UserType`, `PostType`) using `make:graphql:type`.
- Create **queries** (e.g., `UsersQuery`, `PostsQuery`) with `make:graphql:query`.
- Implement **resolvers** with Eloquent or custom logic.
3. **Middleware**:
- Add **execution middleware** (e.g., auth, tracing) in `graphql.execution_middleware`.
- Attach **resolver middleware** for field-level logic (e.g., logging).
4. **Optimizations**:
- Configure **Dataloaders** for batching (e.g., `UserLoader`).
- Enable `SelectFields` for Eloquent optimizations.
5. **Security**:
- Disable introspection in production: `GRAPHQL_DISABLE_INTROSPECTION=true`.
- Set query depth/complexity limits in `config/graphql.php`.
6. **Testing**:
- Write tests using `TestCase` or `TestCaseDatabase`.
- Test mutations with `httpGraphql()` helper.
7. **Deployment**:
- Monitor performance with **OpenTelemetry** or Laravel Debugbar.
- Gradually roll out to clients with **feature flags**.
---
## Operational Impact
### **Maintenance**
- **Schema Evolution**:
- GraphQL’s **schema-first design** encourages **backward-compatible changes** (e.g., adding non-nullable fields with defaults).
- Use **deprecation
How can I help you explore Laravel packages today?